// 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();
};

// Contains an ordered list of commits serialized using the SerializedCommits
// schema defined in serialized_commits.fbs.
//
// TODO(ppi): switch to a format defined in a FIDL table, so that the protocol
// is fully described by the FIDL file.
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);
};
