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