// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// TODO(sadovsky): Finish updating to reflect new, simplified API. Some, but not
// all, has been updated.

// TODO(sadovsky): Copy struct and interface comments from VDL files.
// TODO(sadovsky): Add BlobManager, ConflictManager, and SchemaManager
// methods.

// TODO(sadovsky): This should probably be something else.
module mojo;

// TODO(sadovsky): Put structs in a separate types.mojom file.
// TODO(sadovsky): Loose representation of verror. Improve this.
struct Error {
  string id;  // empty string means no error
  uint32 action_code;
  string msg;
};

// TODO(sadovsky): Decide how to represent perms.
struct Permissions {
  string json;
};

struct Id {
  string blessing;
  string name;
};

struct BatchOptions {
  string hint;
  bool read_only;
};

struct SyncgroupSpec {
  string description;
  Permissions perms;
  array<Id> collections;
  array<string> mount_tables;
  bool is_private;
};

struct SyncgroupMemberInfo {
  uint8 sync_priority;
  uint8 blob_dev_type;
};

struct Result {
  array<array<uint8>> values;
};

// In this model, the server pushes one stream item to the client, then waits
// for an ack from the client before sending the next item, thus providing
// flow control.
[ServiceName="v23::syncbase::ExecStream"]
interface ExecStream {
  OnResult(Result result) => ();
  OnDone(Error err);
};

struct KeyValue {
  string key;
  array<uint8> value;
};

// In this model, the server pushes one stream item to the client, then waits
// for an ack from the client before sending the next item, thus providing
// flow control.
[ServiceName="v23::syncbase::ScanStream"]
interface ScanStream {
  OnKeyValue(KeyValue key_value) => ();
  OnDone(Error err);
};

struct WatchChange {
  Id collection_id;
  string row_key;
  uint32 change_type;
  array<uint8> value_bytes;
  array<uint8> resume_marker;
  bool from_sync;
  bool continued;
};

struct GlobRequest {
  string pattern;
  array<uint8> resume_marker;
};

// In this model, the server pushes one stream item to the client, then waits
// for an ack from the client before sending the next item, thus providing
// flow control.
[ServiceName="v23::syncbase::WatchGlobStream"]
interface WatchGlobStream {
  OnChange(WatchChange change) => ();
  OnError(Error err);
};

// All 'name' params are service-relative object names.

// Error handling modeled after:
// https://github.com/domokit/mojo/blob/master/mojo/services/files/public/interfaces/file.mojom
[ServiceName="v23::syncbase::Syncbase"]
interface Syncbase {
  ////////////////////////////////////////
  // Service

  ServiceGetPermissions() => (Error err, Permissions perms, string version);
  ServiceSetPermissions(Permissions perms, string version) => (Error err);
  ServiceListDatabases() => (Error err, array<Id> databases);

  ////////////////////////////////////////
  // Database

  DbCreate(string name, Permissions perms) => (Error err);
  DbDestroy(string name) => (Error err);
  DbExists(string name) => (Error err, bool exists);
  DbListCollections(string name, string batch_handle)
      => (Error err, array<Id> collections);
  DbExec(
      string name, string batch_handle, string query,
      array<array<uint8>> parameters, ExecStream stream)
      => (Error err);
  DbBeginBatch(string name, BatchOptions opts)
      => (Error err, string batch_handle);
  DbCommit(string name, string batch_handle) => (Error err);
  DbAbort(string name, string batch_handle) => (Error err);
  DbPauseSync(string name) => (Error err);
  DbResumeSync(string name) => (Error err);
  DbGetPermissions(string name)
      => (Error err, Permissions perms, string version);
  DbSetPermissions(string name, Permissions perms, string version)
      => (Error err);
  DbWatchGlob(string name, GlobRequest req, WatchGlobStream stream)
      => (Error err);
  DbGetResumeMarker(string name, string batch_handle)
      => (Error err, array<uint8> resume_marker);

  ////////////////////////////////////////
  // SyncgroupManager

  DbListSyncgroups(string name) => (Error err, array<Id> ids);
  DbCreateSyncgroup(
      string name, Id sg_id, SyncgroupSpec spec,
      SyncgroupMemberInfo my_info)
      => (Error err);
  DbJoinSyncgroup(string name, Id sg_id, SyncgroupMemberInfo my_info)
      => (Error err, SyncgroupSpec spec);
  DbLeaveSyncgroup(string name, Id sg_id) => (Error err);
  DbDestroySyncgroup(string name, Id sg_id) => (Error err);
  DbEjectFromSyncgroup(string name, Id sg_id, string member)
      => (Error err);
  DbGetSyncgroupSpec(string name, Id sg_id)
      => (Error err, SyncgroupSpec spec, string version);
  DbSetSyncgroupSpec(string name, Id sg_id, SyncgroupSpec spec, string version)
      => (Error err);
  DbGetSyncgroupMembers(string name, Id sg_id)
      => (Error err, map<string, SyncgroupMemberInfo> infos);

  ////////////////////////////////////////
  // Collection

  CollectionCreate(string name, string batch_handle, Permissions perms)
      => (Error err);
  CollectionDestroy(string name, string batch_handle) => (Error err);
  CollectionExists(string name, string batch_handle)
      => (Error err, bool exists);
  CollectionGetPermissions(string name, string batch_handle)
      => (Error err, Permissions perms);
  CollectionSetPermissions(string name, string batch_handle, Permissions perms)
      => (Error err);
  CollectionDeleteRange(
      string name, string batch_handle, array<uint8> start, array<uint8> limit)
      => (Error err);
  CollectionScan(
      string name, string batch_handle, array<uint8> start, array<uint8> limit,
      ScanStream stream)
      => (Error err);

  ////////////////////////////////////////
  // Row

  RowExists(string name, string batch_handle) => (Error err, bool exists);
  RowGet(string name, string batch_handle) => (Error err, array<uint8> value);
  RowPut(string name, string batch_handle, array<uint8> value) => (Error err);
  RowDelete(string name, string batch_handle) => (Error err);
};
