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

/// This file contains the definition of Link as well as the structure
/// of the data it holds.

library fuchsia.modular;

using fuchsia.mem;

/// This interface is implemented by the story runner. The ModuleContext service
/// acts as a factory for it.
///
/// An instance of Link holds one of two types of values:
///
/// (1) A JSON string that can be modified incrementally or completely
///     overwritten, depending on the use of Set() and Update(). The JSON string
///     is set to "null" when the Link is created.
///
/// (2) An entity reference that can be set or retrieved with SetEntity() and
///     GetEntity().
///
/// Each Module instance receives one Link instance for each parameter of its
/// action template in its ModuleContext. It receives its ModuleContext in
/// Module.Initialize() or in its service namespace. The Module can access its
/// Links by calling ModuleContext.GetLink() with the intent parameter name as
/// the link name. These instances are shared with the parent Module if there is
/// any, or with the StoryController client if the Module is a top level Module
/// of a Story. A Module can create additional Link instances by calling
/// ModuleContext.GetLink() with any other link name. Why would it do that? To
/// share the new Link instance with Modules it requests to start in turn, or to
/// record its own state in the story record, so that it is transferred to other
/// devices that run the same story, or to persist it for later resumption of the
/// story.
///
/// A client may obtain another handle to the same Link instance by calling
/// GetLink() with the same name again.
///
/// A client of Link can set the JSON string stored in the instance and register
/// a handler (an implementation of the LinkWatcher interface) to be notified of
/// changes to the JSON string in the Link. A client may or may not be notified
/// of changes it itself makes to the Link value, depending on whether it
/// registers with WatchAll() or Watch(), respectively. If the client registers
/// with Watch(), then it will not be notified of changes made through the same
/// Link connection.
///
/// No service name: returned from ModuleContext.GetLink().
protocol Link {
    /// Gets the value at the given `path`, which is represented using the JSON
    /// Pointer specification (https://tools.ietf.org/html/rfc6901).
    ///
    /// `json_data` is a UTF8 encoded string representing valid JSON.
    ///
    /// Returns null if `path` does not exist. Returns the entire JSON object
    /// if `path` is either null or an empty array. Returns the string "null" if
    /// the link is empty.
    Get(vector<string>? path) -> (fuchsia.mem.Buffer? json_data);

    /// Set() overwrites the value/object/array at the given `path`. Set also
    /// overwrites any values or arrays as necessary to ensure that `path` exists.
    /// The `json_data` parameter must be a UTF8 encoded JSON string.
    /// Either pass "null" to set the value to null, or use Erase to
    /// completely remove a member of an object. To replace the root, pass null for
    /// `path`.
    ///
    /// This call notifies Watchers, although this may be skipped if nothing
    /// changed.
    Set(vector<string>? path, fuchsia.mem.Buffer json_data);

    /// Erases the object member at the given `path`. If the path is not found or
    /// does not match the current structure of the JSON, the path will not be
    /// created and the call is ignored. The `path` parameter cannot be null or
    /// zero length because the root is a value, not a key. This call notifies
    /// Watchers, although this may be skipped if nothing changed.
    Erase(vector<string> path);

    /// Returns the entity reference in this link. If no entity reference is
    /// present, returns a null fidl string.
    GetEntity() -> (string? entity_reference);

    /// Sets this to be an Entity Link with the given `entity_reference`. The
    /// existing value of the link is overwritten. If `entity_reference` is null,
    /// then any existing value in the link is overwritten with the JSON string
    /// "null".
    SetEntity(string? entity_reference);

    /// Registers a watcher, which is notified whenever the document changes. This
    /// watcher will not be invoked for changes caused by calls made on this
    /// handle. The Notify() callback method will be immediately invoked with the
    /// value in the Link, even if it's empty.
    ///
    /// The LinkWatcher connection will be closed if the owning Link handle closed.

    /// All connections to a Link and LinkWatcher are closed once the story the
    /// link belongs to is stopped.
    Watch(LinkWatcher watcher);

    /// Like Watch(), but the watcher is notified also of changes made through the
    /// same handle as the watcher is registered on.
    WatchAll(LinkWatcher watcher);

    /// Waits for the completion of methods previously invoked on the same
    /// connection. Allows to create sequentiality across service instances without
    /// giving every method an empty return value. Nb. this makes no guarantees
    /// about sequentiality with methods invoked on different connections, even to
    /// the same Link instance.
    Sync() -> ();
};

/// This interface is implemented by a client of Link.
///
/// The Notify() method is invoked whenever the Link changes. The entire JSON
/// string in the Link will be sent. In other words, this isn't an incremental
/// notification. `json` cannot be null because an empty Link is the valid JSON
/// document "null".
///
/// No service name: created by Module.
protocol LinkWatcher {
    Notify(fuchsia.mem.Buffer json);
};
