// 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): Copy struct and interface comments from VDL files.

// 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 Perms {
  string json;
};

struct BatchOptions {
  string hint;
  bool read_only;
};

struct PrefixPerms {
  string prefix;
  Perms perms;
};

struct SyncGroupSpec {
  string description;
  Perms perms;
  array<string> prefixes;
  array<string> mount_tables;
  bool is_private;
};

struct SyncGroupMemberInfo {
  uint8 sync_priority;
};

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

interface ExecStream {
  OnResult(Result result);
  OnReturn(Error err);
};

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

// ScanStream implements the observer + ack pattern.
// In this model, server pushes a change object and waits until it receives
// an ack back from client before sending the next KeyValue, effectively
// creating a mechanism for flow control.
interface ScanStream {
  // TODO(aghassemi): Same TODO as WatchGlobStream.OnChange
  OnKeyValue(KeyValue key_value) => (bool ack);
  OnReturn(Error err);
};

struct WatchChange {
  string table_name;
  string row_name;
  uint32 change_type;
  array<uint8> value_bytes;
  array<uint8> resume_marker;
  bool from_sync;
  bool continued;
};

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

// WatchGlobStream implements the observer + ack pattern.
// In this model, server pushes a change object and waits until it receives
// an ack back from client before sending the next change, effectively creating
// a mechanism for flow control.
interface WatchGlobStream {
  // TODO(aghassemi): We should be able to do => () instead of => (bool ack)
  // but mojom Go compiler has a bug where it does not differentiate between
  // no return and => () therefore call does not actually block until callback
  // is called. This is a bug and for now we get around it by returning a bool.
  // See https://github.com/vanadium/issues/issues/749 for details.
  OnChange(WatchChange change) => (bool ack);
  OnError(Error err);
};

// TODO(sadovsky): Add schema version to all RPCs. See v.io/c/13734.
// TODO(sadovsky): Add ListApps, ListDatabases, and ListTables methods.
// 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
interface Syncbase {
  ////////////////////////////////////////
  // Service

  ServiceGetPermissions() => (Error err, Perms perms, string version);
  ServiceSetPermissions(Perms perms, string version) => (Error err);

  ////////////////////////////////////////
  // App

  AppCreate(string name, Perms perms) => (Error err);
  AppDestroy(string name) => (Error err);
  AppExists(string name) => (Error err, bool exists);
  AppGetPermissions(string name) => (Error err, Perms perms, string version);
  AppSetPermissions(string name, Perms perms, string version) => (Error err);

  ////////////////////////////////////////
  // nosql.Database

  // TODO(sadovsky): Add SchemaMetadata argument.
  DbCreate(string name, Perms perms) => (Error err);
  DbDestroy(string name) => (Error err);
  DbExists(string name) => (Error err, bool exists);
  DbExec(string name, string query, ExecStream stream) => (Error err);
  DbBeginBatch(string name, BatchOptions? bo) => (Error err, string batch_suffix);
  DbCommit(string name) => (Error err);
  DbAbort(string name) => (Error err);
  DbGetPermissions(string name) => (Error err, Perms perms, string version);
  DbSetPermissions(string name, Perms perms, string version) => (Error err);
  DbWatchGlob(string name, GlobRequest req, WatchGlobStream stream) => (Error err);
  DbGetResumeMarker(string name) => (Error err, array<uint8> resumeMarker);

  // TODO(sadovsky): Add DatabaseWatcher, BlobManager, and SchemaManager
  // methods.

  ////////////////////////////////////////
  // nosql.Database: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);

  ////////////////////////////////////////
  // nosql.Table

  TableCreate(string name, Perms perms) => (Error err);
  TableDestroy(string name) => (Error err);
  TableExists(string name) => (Error err, bool exists);
  TableGetPermissions(string name) => (Error err, Perms perms);
  TableSetPermissions(string name, Perms perms) => (Error err);
  TableDeleteRange(string name, array<uint8> start, array<uint8> limit)
      => (Error err);
  TableScan(
      string name, array<uint8> start, array<uint8> limit, ScanStream stream)
      => (Error err);
  TableGetPrefixPermissions(string name, string key)
      => (Error err, array<PrefixPerms> perms_arr);
  TableSetPrefixPermissions(string name, string prefix, Perms perms) => (Error err);
  TableDeletePrefixPermissions(string name, string prefix) => (Error err);

  ////////////////////////////////////////
  // nosql.Row

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