// 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.

/// 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;
    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]
interface CloudProvider {
    /// Retrieves the controller for the user device set.
    1: GetDeviceSet(request<DeviceSet> device_set) -> (Status status);

    /// Retrieves the controller for cloud sync of a particular page.
    2: GetPageCloud(vector<uint8> app_id, vector<uint8> 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.
interface 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.
    1: CheckFingerprint(vector<uint8> fingerprint) -> (Status status);

    /// Adds the device fingerprint to the list of devices in the cloud.
    2: SetFingerprint(vector<uint8> 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.
    3: SetWatcher(vector<uint8> fingerprint, DeviceSetWatcher watcher)
           -> (Status status);

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

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

    /// Called when the network connection is lost. No further calls are made on
    /// the watcher after this is called.
    2: OnNetworkError();
};

// TODO(ppi): switch to a format defined in a FIDL table, so that the protocol
// is fully described by the FIDL file.
/// Contains an ordered list of commits serialized using the SerializedCommits
/// schema defined in serialized_commits.fbs.
struct CommitPack {
    fuchsia.mem.Buffer buffer;
};

/// A continuation token for paginated requests.
struct Token {
    vector<uint8> opaque_id;
};

/// 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.
interface 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.
    1: 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).
    2: GetCommits(Token? min_position_token)
           -> (Status status, CommitPack? commits, Token? 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.
    3: AddObject(vector<uint8> id, fuchsia.mem.Buffer buffer) -> (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.
    4: GetObject(vector<uint8> 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.
    5: SetWatcher(Token? min_position_token, PageCloudWatcher watcher)
           -> (Status status);
};

/// Watcher for push notifications from cloud sync of a single page.
interface 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 the client calls the callback of the
    /// previous one.
    1: OnNewCommits(CommitPack commits, Token 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 the client calls the callback of the
    /// previous one.
    2: OnNewObject(vector<uint8> id, fuchsia.mem.Buffer buffer) -> ();

    /// Called when an error occurs.
    ///
    /// No further calls are made on the watcher after this is called. The client
    /// 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
    3: OnError(Status status);
};
