// 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.
library fuchsia.component.runner;

using fuchsia.component;
using fuchsia.data;
using fuchsia.diagnostics.types;
using fuchsia.io;
using fuchsia.process;
using fuchsia.url;

const MAX_NAMESPACE_COUNT uint32 = 32;
const MAX_HANDLE_COUNT uint32 = 128;

/// A protocol used for running components.
///
/// This protocol is implemented by components which provide a runtime
/// environment for other components.
///
/// Note: The component manager is the only intended direct client of this
/// interface.
@discoverable
protocol ComponentRunner {
    /// Start running a component instance described by `start_info`.
    ///
    /// Component manager binds and uses `controller` to control the
    /// lifetime of the newly started component instance.
    ///
    /// Errors are delivered as epitaphs over the `ComponentController`
    /// protocol. In the event of an error, the runner must ensure that
    /// resources are cleaned up.
    ///
    /// Errors:
    ///
    Start(resource struct {
        start_info ComponentStartInfo;
        controller server_end:ComponentController;
    });
};

/// A single component namespace entry, which describes a namespace mount point
/// (`path`) and the directory backing it (`directory`). This type is usually
/// composed inside a vector.  See `ComponentStartInfo.ns` for more details.
type ComponentNamespaceEntry = resource table {
    /// The mount point for the directory, including a
    /// leading slash. For example: "/pkg", "/svc", or "/config/data".
    1: path string:fuchsia.component.MAX_PATH_LENGTH;

    /// The directory mounted at the above `path`.
    2: directory client_end:fuchsia.io.Directory;
};

/// Parameters for starting a new component instance.
type ComponentStartInfo = resource table {
    /// The resolved URL of the component.
    ///
    /// This is the canonical URL obtained by the component resolver after
    /// following redirects and resolving relative paths.
    1: resolved_url fuchsia.url.Url;

    /// The component's program declaration.
    /// This information originates from `ComponentDecl.program`.
    2: program fuchsia.data.Dictionary;

    /// The namespace to provide to the component instance.
    ///
    /// A namespace specifies the set of directories that a component instance
    /// receives at start-up. Through the namespace directories, a component
    /// may access capabilities available to it. The contents of the namespace
    /// are mainly determined by the component's `use` declarations but may
    /// also contain additional capabilities automatically provided by the
    /// framework.
    ///
    /// By convention, a component's namespace typically contains some or all
    /// of the following directories:
    ///
    /// - "/svc": A directory containing services that the component requested
    ///           to use via its "import" declarations.
    /// - "/pkg": A directory containing the component's package, including its
    ///           binaries, libraries, and other assets.
    ///
    /// The mount points specified in each entry must be unique and
    /// non-overlapping. For example, [{"/foo", ..}, {"/foo/bar", ..}] is
    /// invalid.
    3: ns vector<ComponentNamespaceEntry>:MAX_NAMESPACE_COUNT;

    /// The directory this component serves.
    4: outgoing_dir server_end:fuchsia.io.Directory;

    /// The directory served by the runner to present runtime information about
    /// the component.
    5: runtime_dir server_end:fuchsia.io.Directory;

    /// The numbered handles that were passed to the component.
    ///
    /// If the component does not support numbered handles, the runner is expected
    /// to close the handles.
    6: numbered_handles vector<fuchsia.process.HandleInfo>:MAX_HANDLE_COUNT;
};

/// A protocol for binding and controlling the lifetime of a component instance
/// started using `ComponentRunner.Start()`. The component manager is the
/// intended direct client of this protocol.
///
/// When the controlled component instance terminates or becomes inaccessible
/// for any reason, the server closes the connection with an epitaph.
///
/// LIFECYCLE
///
/// A component may exist in one of two states: `Started`, or `Stopped`. The
/// component is `Started` from the time `ComponentRunner.Start()` is called
/// until the ComponentRunner closes the ComponentController handle. The
/// component then transitions to `Stopped`.
///
/// Component manager uses ComponentController to terminate a component in two
/// steps:
///  1) Component manager calls `Stop()` to indicate that the ComponentRunner
///     should stop a component's execution and close this connection with an
///     epitaph.
///  2) If after some time the ComponentController is not closed, component
///     manager calls `Kill()` to indicate that the ComponentRunner must halt a
///     component's execution immediately, and then close this connection with
///     an epitaph.
///
/// Component manager first waits for the ComponentController to close, and
/// then tears down the namespace it hosts for the stopped component. Component
/// manager may call `Kill()` without first having called `Stop()`.
///
/// EPITAPH
///
/// This protocol sends a FIDL epitaph to indicate that the component instance
/// has been terminated. The component runner is expected to clean up all
/// resources attributed to the component before closing the connection.
///
/// The following epitaphs may be sent by the server on error:
/// - `ZX_OK`: The component exited successfully, typically because the
///   component was asked to stop or it decided independently to exit.
/// - `INVALID_ARGUMENTS`:
///     * `start_info.resolved_url` is not supported by this
///       runner;
///     * `start_info` contains missing or invalid arguments.
/// - `INSTANCE_CANNOT_START`: The runner could not start the component.
///   For example, a critical part of the program could not be found or
///   loaded, or the referenced binary was invalid for this runner.
/// - `RESOURCE_UNAVAILABLE`: The component could not be launched due to
///   lack of resources.
/// - `INTERNAL`: An unexpected internal runner error was encountered.
/// - `INSTANCE_DIED`: The component instance was started but
///   subsequently terminated with an error.
/// - Other status codes (e.g. `ZX_ERR_PEER_CLOSED`) may indicate a failure
///   of the component runner itself. The component manager may respond to such
///   failures by terminating the component runner's job to ensure system
///   stability.
protocol ComponentController {
    /// Request to stop the component instance.
    ///
    /// After stopping the component instance, the server should close this
    /// connection with an epitaph. After the connection
    /// closes, component manager considers this component instance to be
    /// Stopped and the component's namespace will be torn down.
    Stop();

    /// Stop this component instance immediately.
    ///
    /// The ComponentRunner must immediately kill the component instance, and
    /// then close this connection with an epitaph. After the connection
    /// closes, component manager considers this component instance to be
    /// Stopped and the component's namespace will be torn down.
    ///
    /// In some cases Kill() may be issued before Stop(), but that is not
    /// guaranteed.
    Kill();

    /// Event for runners to publish diagnostics to the platform.
    ///
    /// This event signals to the platform that the runner for this
    /// component is publishing diagnostics about the runtime of the
    /// component. The component manager may optionally expose this data
    /// to clients.
    -> OnPublishDiagnostics(resource struct {
        payload fuchsia.diagnostics.types.ComponentDiagnostics;
    });
};
