// Copyright 2019 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.session;

using fuchsia.io;
using fuchsia.io2;
using fuchsia.url;

/// The ElementManager is responsible for service requests to add elements to a
/// session.
///
/// An Element is a component which is expected to be instantiated as a child
/// of the session and interact with the user in some way.
///
/// For example, a component acting as an element proposer may be listening to
/// the network for instructions to display an element to the user. When such
/// a network command is received, the element proposer proposes to add an
/// element to the session via the `ElementManager` protocol.
[Discoverable]
protocol ElementManager {
    /// Proposes to add an Element to the session.
    ///
    /// If `ProposeElement()` returns without error, the caller can assume
    /// the element is now part of the session. However, whether or not the
    /// element component is actively running, or not, is left to the session's
    /// discretion. For example, a session may decide to conserve resources by
    /// suspending an element which is not in focus, or delay the running of an
    /// element until a more appropriate time.
    ///
    /// `spec` describes the Element to add.
    /// `element_controller` can be used to set and get annotations on the Element
    ///     created by the `ElementManager`.
    ProposeElement(ElementSpec spec, request<ElementController>? element_controller)
        -> () error ProposeElementError;
};

protocol ElementController {
    /// The server is expected to adhere to the following conventions:
    /// * If a key is new, a new annotation is added.
    /// * If a key already exists, the annotation is updated.
    /// * If a key exists with a null value, the annotation is deleted.
    SetAnnotations(Annotations annotations) -> () error AnnotationError;

    /// Returns the current `Annotations` for the controlled element.
    GetAnnotations() -> (Annotations annotations) error AnnotationError;
};

/// Errors which can be returned when attempting to add elements to a session.
enum ProposeElementError {
    /// There was an error resolving the element's component url.
    NOT_FOUND = 1;

    /// The session rejected the proposal to add the element. Reasons may include
    /// errors with components of the ElementSpec. (See `AnnotationError` for
    /// some specific examples.)
    REJECTED = 2;
};

/// Describes an Element to be added to a session.
table ElementSpec {
    /// The component URL of the Element.
    1: fuchsia.url.Url component_url;

    /// Initial metadata on the element. Optional.
    2: Annotations annotations;

    // TODO(fxb/44648): Remove this field after converting all components to Component Framework v2,
    // unless the concept of providing services in this way has been approved for dynamically-routed
    // v2->v2 interactions.
    /// Requests the Element Manager forward the given capabilities to the component at launch.
    /// The Element Manager should forward these capabilities to the relevant Runner, and the
    /// Runner should expose these capabilities to the launched component's incoming namespace.
    /// (This mechanism allows backward compatibility for Runners to launch v1 (`.cmx`) components
    /// that require additional services.)
    3: AdditionalCapabilities additional_capabilities;
};

// TODO(fxb/44648): Remove this field after converting all components to Component Framework v2,
// unless the concept of providing services in this way has been approved for dynamically-routed
// v2->v2 interactions.
/// Provides a list of capabilities to be offered to a proposed element, and a Directory from which
/// another component can connect to the implementations of those capabilities.
struct AdditionalCapabilities {
    /// A list of capabilities by absolute path name, relative to the given host_directory (for
    /// example, "/svc/fuchsia.util.SomeService").
    vector<fuchsia.io2.Path>:MAX paths;

    /// The `Directory` from which the capabilities are served.
    fuchsia.io.Directory host_directory;
};
