@namespace("keybase.1")

protocol metadata {
  import idl "backend_common.avdl";

  record KeyHalf {
         UID user;
         KID deviceKID;
         bytes key;
  }

  record MDBlock {
         int version;
         Time timestamp;
         bytes block;
  }

  record KeyBundle {
         int version;
         bytes bundle;
  }

  record MetadataResponse {
         string folderID;
         array<MDBlock> mdBlocks;
  }

  record MerkleRoot {
         int version;
         bytes root;
  }

  record PingResponse {
         Time timestamp;
  }

  record KeyBundleResponse {
         @lint("ignore")
         KeyBundle WriterBundle;
         @lint("ignore")
         KeyBundle ReaderBundle;
  }

  ChallengeInfo getChallenge();
  int authenticate(string signature);
  void putMetadata(MDBlock mdBlock, KeyBundle readerKeyBundle, KeyBundle writerKeyBundle, map<string> logTags);
  MetadataResponse getMetadata(string folderID, bytes folderHandle, string branchID, boolean unmerged, long startRevision, long stopRevision, map<string> logTags);
  void registerForUpdates(string folderID, long currRevision, map<string> logTags);
  void pruneBranch(string folderID, string branchID, map<string> logTags);
  void putKeys(array<KeyHalf> keyHalves, map<string> logTags);
  bytes getKey(bytes keyHalfID, string deviceKID, map<string> logTags);
  void deleteKey(UID uid, KID deviceKID, bytes keyHalfID, map<string> logTags);
  boolean truncateLock(string folderID);
  boolean truncateUnlock(string folderID);
  bytes getFolderHandle(string folderID, string signature, string challenge);
  void getFoldersForRekey(KID deviceKID);
  void ping();
  PingResponse ping2();
  bytes getLatestFolderHandle(string folderID);
  KeyBundleResponse getKeyBundles(string folderID, string writerBundleID, string readerBundleID);

  // Merkle tree specific commands
  // todo: we probably also want a method which will return a minmum set of interior nodes
  // and a leaf node given a root node and a TLF ID.
  MerkleRoot getMerkleRoot(MerkleTreeID treeID, long seqNo);
  MerkleRoot getMerkleRootLatest(MerkleTreeID treeID);
  MerkleRoot getMerkleRootSince(MerkleTreeID treeID, Time when);
  bytes getMerkleNode(string hash);
}
