// 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 CollectionRow {
  Id collection_id;
  string row;
};

struct SyncgroupSpec {
  string description;
  Permissions perms;
  array<CollectionRow> prefixes;
  array<string> mount_tables;
  bool is_private;
};

struct SyncgroupMemberInfo {
  uint8 sync_priority;
};

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

  DbGetSyncgroupNames(string name) => (Error err, array<string> names);
  DbCreateSyncgroup(
      string name, string sg_name, SyncgroupSpec spec,
      SyncgroupMemberInfo my_info)
      => (Error err);
  DbJoinSyncgroup(string name, string sg_name, SyncgroupMemberInfo my_info)
      => (Error err, SyncgroupSpec spec);
  DbLeaveSyncgroup(string name, string sg_name) => (Error err);
  DbDestroySyncgroup(string name, string sg_name) => (Error err);
  DbEjectFromSyncgroup(string name, string sg_name, string member)
      => (Error err);
  DbGetSyncgroupSpec(string name, string sg_name)
      => (Error err, SyncgroupSpec spec, string version);
  DbSetSyncgroupSpec(
      string name, string sg_name, SyncgroupSpec spec, string version)
      => (Error err);
  DbGetSyncgroupMembers(string name, string sg_name)
      => (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);
};
