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

library fuchsia.ledger.cloud;

using fuchsia.mem;

// This file defines a cloud service that can be used by Ledger to power cloud
// sync.

/// Identifier for a commit, controlled by Ledger.
using CommitIdentifier = bytes:128;

/// Identifier for an object, controlled by Ledger.
using ObjectIdentifier = bytes:128;

/// Identifier for an entry, controlled by Ledger.
using EntryIdentifier = bytes:64;

/// Fingerprint, controlled by Ledger and used to watch for cloud erasure.
using Fingerprint = bytes:32;

/// Response status for cloud provider operations.
enum Status : int32 {
    OK = 0;
    AUTH_ERROR = 1;
    ARGUMENT_ERROR = 2;
    INTERNAL_ERROR = 3;
    NETWORK_ERROR = 4;
    NOT_FOUND = 5;
    PARSE_ERROR = 6;
    SERVER_ERROR = 7;
    NOT_SUPPORTED = 8;
    UNKNOWN_ERROR = -1;
};

/// Cloud service that powers cloud sync for a single user. Top-level interface
/// of this file.
///
/// Closing the client connection to CloudProvider shuts down all controllers
/// (DeviceSets, PageClouds) that were produced by it.
[Discoverable]
protocol CloudProvider {
    /// Retrieves the controller for the user device set.
    GetDeviceSet(request<DeviceSet> device_set) -> (Status status);

    /// Retrieves the controller for cloud sync of a particular page.
    GetPageCloud(bytes app_id, bytes page_id, request<PageCloud> page_cloud)
        -> (Status status);
};

/// Cloud registry of devices participating in cloud sync.
///
/// Closing the client connection to DeviceSet disconnects all watchers set on
/// it.
protocol DeviceSet {
    /// Verifies that the device fingerprint in the cloud is still in the list of
    /// devices, ensuring that the cloud was not erased since the last sync.
    CheckFingerprint(Fingerprint fingerprint) -> (Status status);

    /// Adds the device fingerprint to the list of devices in the cloud.
    SetFingerprint(Fingerprint fingerprint) -> (Status status);

    /// Watches the given `fingerprint` in the cloud so that `watcher` is notified
    /// when the fingerprint is erased.
    ///
    /// At most one watcher can be set at any given time. If more than one watcher
    /// is set, only the one set most recently receives notifications.
    ///
    /// The returned status is:
    ///
    ///   - OK, if setting the watcher succeeded,
    ///   - `NOT_FOUND`, if the fingerprint was not found in the cloud
    ///   - `NETWORK_ERROR`, if the watcher couldn't be set due to a network error
    ///
    /// If the returned status is not OK, the corresponding error call is also made
    /// on the watcher.
    SetWatcher(Fingerprint fingerprint, DeviceSetWatcher watcher)
        -> (Status status);

    /// Erases the entire registry of devices. This makes all devices detect that
    /// cloud has been erased.
    Erase() -> (Status status);
};

/// Watcher for push notifications from the cloud registry of devices
/// participating in cloud sync.
protocol DeviceSetWatcher {
    /// Called when cloud provider detects that the cloud storage was erased. No
    /// further calls are made on the watcher after this is called.
    OnCloudErased();

    /// Called when an error occured. Most common errors are:
    ///   - `NOT_FOUND`, if the fingerprint was not found in the cloud when registering the watcher.
    ///   - `NETWORK_ERROR` if the network connection is lost.
    ///
    /// No further calls are made on the watcher after this is called.
    OnError(Status status);
};

/// Contains a Buffer containing the FIDL serialization of Commits.
struct CommitPack {
    fuchsia.mem.Buffer buffer;
};

/// An opaque representation of a position in the stream of commits handled by
/// a PageCloud instance.
struct PositionToken {
    bytes opaque_id;
};

/// A commit as seen by the cloud.
table Commit {
    /// A unique commit identifier, chosen by Ledger. Required.
    ///
    /// Two commits uploaded with the same identifier are to be considered
    /// identical: they will have the same parents if present, and the cloud may
    /// return the data and the diff from any of the uploads.
    1: CommitIdentifier id;
    /// Opaque data stored by Ledger. Required.
    2: bytes data;
    /// A diff describing the content of the page at this commit. Optional.
    ///
    /// Ledger will not send a diff for all commits: it may omit the diff when it
    /// determines the content of the commit will not be used by any other Ledger
    /// instance. During the transition to diffs, diff-unaware Ledgers will also
    /// omit the diff.
    /// The cloud provider should not include diffs in the commits it sends to
    /// Ledger.
    // TODO(LE-823): update once the transition to diffs is complete.
    3: Diff diff;
};

/// Specification of a page state used as base for a diff.
xunion PageState {
    /// The state is the empty page.
    EmptyPage empty_page;
    /// The state is the content of a page at the commit with the given
    /// identifier.
    CommitIdentifier at_commit;
};

struct EmptyPage {
};

/// A diff from a base state to a commit.
///
/// Diffs are sequences of insertions and deletions. Updates are encoded as a
/// deletion followed by an insertion. The cloud can match insertions and
/// deletions by an entry identifier chosen by Ledger (because of encryption,
/// the data will not match between insertions and deletions).
table Diff {
    /// Page state used as a reference point for the diff.
    ///
    /// Ledger only uses as base state a commit that is already known to the
    /// cloud, or the empty page.
    1: PageState base_state;
    /// List of changes from the base state to the commit.
    ///
    /// The changes are to be applied in order.
    2: vector<DiffEntry>:MAX changes;
};

/// An entry in a Diff.
table DiffEntry {
    /// Identifier of the entry. Required.
    1: EntryIdentifier entry_id;
    /// Insertion or deletion. Required.
    2: Operation operation;
    /// Data representing the content of the entry.
    ///
    /// Required in diffs sent from Ledger. The cloud provider may omit this
    /// information if the operation is a deletion. If an entry id was inserted/
    /// deleted multiple times, the cloud provider can send any of the values.
    3: bytes:512 data;
    /// An optional reference to an object, given by its identifier.
    ///
    /// Sent by Ledger when the value of the entry is not inlined in the `data`
    /// field. The cloud provider may always omit this field in diffs.
    4: ObjectIdentifier reference;
};

enum Operation : uint8 {
    INSERTION = 1;
    DELETION = 2;
};

/// A list of commits for serialization in CommitPack.
struct Commits {
    vector<Commit>:MAX commits;
};

/// A list of references for serialization in ReferencePack.
struct References {
    vector<ObjectIdentifier>:MAX references;
};

/// Contains a Buffer containing the FIDL serialization of Diff.
struct DiffPack {
    fuchsia.mem.Buffer buffer;
};

/// Contains a Buffer containing the FIDL serialization of References.
///
/// If the Buffer is absent, the reference list is treated as empty.
struct ReferencePack {
    fuchsia.mem.Buffer? buffer;
};

/// Handler for cloud sync of a single page.
///
/// Implementation of this class manages a *commit log*, which is an append-only
/// list of commits produced by all devices that participate in syncing this
/// page. Position of commits within the log are references using position
/// tokens, allowing the caller to retrieve the commits added to the cloud since
/// the previous read. (plus possibly more - see comments for GetCommits() and
/// SetWatcher().)
///
/// Closing the client connection to PageCloud disconnects all watchers set on
/// it.
protocol PageCloud {
    /// Adds the given commits to the commit log in the cloud.
    ///
    /// The commits are added in one batch, on the receiving side they are
    /// delivered in the same order in a single OnNewCommits() call.
    AddCommits(CommitPack commits) -> (Status status);

    /// Retrieves commits from the cloud.
    ///
    /// All commits newer than `min_position_token` are guaranteed to be returned.
    /// In addition to that, the response may include additional commits older
    /// than or at `min_position_token`. Passing null `min_position_token`
    /// retrieves all commits.
    ///
    /// If the resulting `status` is `OK`, `commits` contains all matching commits
    /// (might be empty) and `position_token` contains the position token of the
    /// most recent of the `commits` (equivalent to `min_position_token` if
    /// `commits` is empty).
    GetCommits(PositionToken? min_position_token)
        -> (Status status, CommitPack? commits, PositionToken? position_token);

    /// Uploads the given object to the cloud under the given id.
    ///
    /// If the object already exists in the cloud this method returns OK.
    AddObject(ObjectIdentifier id, fuchsia.mem.Buffer buffer, ReferencePack references)
        -> (Status status);

    /// Retrieves the object of the given id from the cloud.
    ///
    /// If the resulting `status` is `OK`, `buffer` will contain the object
    /// content. If the resulting `status` is not `OK`, `buffer` will be null.
    GetObject(ObjectIdentifier id)
        -> (Status status, fuchsia.mem.Buffer? buffer);

    /// Watches the cloud for push notifications.
    ///
    /// At most one watcher can be set at any given time. If more than one watcher
    /// is set, only the one set most recently receives notifications.
    ///
    /// All commits newer than `min_position_token` added to the cloud before or
    /// after making this call are guaranteed to be delivered to `watcher`. In
    /// addition to that, additional commits older than or at `min_position_token`
    /// may be delivered to. If `min_position_token` is null, notifications for
    /// all commits are delivered.
    SetWatcher(PositionToken? min_position_token, PageCloudWatcher watcher)
        -> (Status status);

    /// Fetches a diff for the commit with the given |commit_id|.
    ///
    /// The base of the diff is either the empty page or a commit in
    /// `possible_bases`. The bases may be unknown to the cloud if they have
    /// been pruned from the cloud, but not from the Ledger. During the
    /// migration to diffs, the cloud provider may also choose as a base any
    /// commit that has been uploaded without diff. In that case, the tree at
    /// this commit should be downloaded using GetObject.
    // TODO(LE-823): update once the transition to diffs is complete.
    GetDiff(CommitIdentifier commit_id, vector<CommitIdentifier>:32 possible_bases)
        -> (Status status, DiffPack? diff);
};

/// Watcher for push notifications from cloud sync of a single page.
protocol PageCloudWatcher {
    /// Called when new commits are added to the commit log in the cloud.
    ///
    /// The method takes the list of new `commits` along with the `position_token`
    /// of the most recent of them.
    ///
    /// No subsequent calls are made until Ledger calls the callback of the
    /// previous one.
    OnNewCommits(CommitPack commits, PositionToken position_token) -> ();

    /// Called when a new object is added to the cloud.
    ///
    /// The method takes the `id` and the content of the new object.
    ///
    /// No subsequent calls are made until Ledger calls the callback of the
    /// previous one.
    OnNewObject(ObjectIdentifier id, fuchsia.mem.Buffer buffer) -> ();

    /// Called when an error occurs.
    ///
    /// No further calls are made on the watcher after this is called. Ledger
    /// can then re-establish the watcher by calling SetWatcher() again.
    ///
    /// The status is one of:
    ///
    ///   - `AUTH_ERROR`, if the auth token needs a refresh
    ///   - `NETWORK_ERROR`, if the connection was dropped
    ///   - `PARSE_ERROR`, if an invalid server notification was received
    OnError(Status status);
};
