// Copyright 2021 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.test;

using fuchsia.component;
using fuchsia.component.decl;
using fuchsia.component.runner;
using fuchsia.component.types;
using fuchsia.data;
using fuchsia.mem;
using fuchsia.io;
using fuchsia.url;

// The Realm Builder Server will include a local component's name in its
// program dictionary under this string. Clients should use this value when
// extracting a local component's name.
const LOCAL_COMPONENT_NAME_KEY string = "LOCAL_COMPONENT_NAME";

/// This protocol can be used to instruct the Realm Builder Server to begin
/// creating a new realm.
@discoverable
protocol RealmBuilderFactory {
    /// Creates a new RealmBuilder. The client end of `realm_server_end` can be
    /// used to mutate the realm that is being constructed, by doing things such
    /// as adding new children to the realm or adding capability routes between
    /// them. The client end of `builder_server_end` is used to finalize the
    /// realm, after which point it can be launched in a collection.
    Create(resource struct {
        pkg_dir_handle client_end:fuchsia.io.Directory;
        realm_server_end server_end:Realm;
        builder_server_end server_end:Builder;
    }) -> ();

    /// Identical to `Create`, but instead of the realm being empty by default
    /// it contains the contents of the manifest located at `relative_url`
    /// within `pkg_dir_handle`.
    CreateFromRelativeUrl(resource struct {
        pkg_dir_handle client_end:fuchsia.io.Directory;
        relative_url fuchsia.url.Url;
        realm_server_end server_end:Realm;
        builder_server_end server_end:Builder;
    }) -> (struct {}) error RealmBuilderError2;
};

/// Errors that may be returned by the `Realm` and `Builder` protocols.
///
/// Will be renamed to `RealmBuilderError` once the other definition under this
/// name earlier in this file is removed.
type RealmBuilderError2 = strict enum : uint32 {
    /// Child cannot be added to the realm, as there is already a child in the
    /// realm with that name.
    CHILD_ALREADY_EXISTS = 0;

    /// A legacy component URL was given to `AddChild`, or a modern component
    /// url was given to `AddLegacyChild`.
    INVALID_MANIFEST_EXTENSION = 1;

    /// A component declaration failed validation.
    INVALID_COMPONENT_DECL = 2;

    /// The referenced child does not exist.
    NO_SUCH_CHILD = 3;

    /// The component declaration for the referenced child cannot be viewed nor
    /// manipulated by RealmBuilder, because the child was added to the realm
    /// using an URL that was neither a relative nor a legacy URL.
    CHILD_DECL_NOT_VISIBLE = 4;

    /// The source does not exist.
    NO_SUCH_SOURCE = 5;

    /// A target does not exist.
    NO_SUCH_TARGET = 6;

    /// The `capabilities` field is empty.
    CAPABILITIES_EMPTY = 7;

    /// The `targets` field is empty.
    TARGETS_EMPTY = 8;

    /// The `from` value is equal to one of the elements in `to`.
    SOURCE_AND_TARGET_MATCH = 9;

    /// The test package does not contain the component declaration referenced
    /// by a relative URL.
    DECL_NOT_FOUND = 10;

    /// Encountered an I/O error when attempting to read a component declaration
    /// referenced by a relative URL from the test package.
    DECL_READ_ERROR = 11;

    /// The `Build` function has been called multiple times on this channel.
    BUILD_ALREADY_CALLED = 12;

    /// A capability is invalid. This may occur if a required field is empty or
    /// if an unsupported type is received.
    CAPABILITY_INVALID = 13;

    /// The handle the client provided for the child realm is not usable.
    INVALID_CHILD_REALM_HANDLE = 14;

    /// `ReplaceComponentDecl` was called on a legacy or local component with a
    /// program declaration that did not match the one from the old component
    /// declaration. This could render a legacy or local component
    /// non-functional, and is disallowed.
    IMMUTABLE_PROGRAM = 15;

    /// The URL provided to `RealmBuilderFactory.CreateFromRelativeURL` is not a
    /// relative URL.
    URL_IS_NOT_RELATIVE = 16;

    /// The handle the client provided for the test's pkg directory is not
    /// usable.
    INVALID_PKG_DIR_HANDLE = 17;
};

protocol Builder {
    /// Assembles the realm being constructed and returns the URL for the root
    /// component in the realm, which may then be used to create a new component
    /// in any collection where fuchsia-test-component is properly set up. Once
    /// this is called, any Realm channels for the realm will no longer be
    /// usable. The `runner` argument must be provided if the `AddLocalChild`
    /// function has been used in this realm, as this runner channel will be
    /// used to inform the client when to start and stop running any local
    /// component implementations.
    ///
    /// Errors:
    /// - `INVALID_COMPONENT_DECL`: A component declaration failed validaiton.
    /// - `BUILD_ALREADY_CALLED`: The `Build` function has been called multiple
    ///   times on this channel.
    Build(resource struct {
        runner client_end:fuchsia.component.runner.ComponentRunner;
    }) -> (struct {
        root_component_url string:fuchsia.component.types.MAX_URL_LENGTH;
    }) error RealmBuilderError2;
};

/// A capability that can be routed around a realm using `AddRoute`.
///
/// Will be renamed to `Capability` once the other definition under this name
/// earlier in this file is removed.
type Capability2 = flexible union {
    1: protocol Protocol;
    2: directory Directory;
    3: storage Storage;
    4: service Service;
    5: event Event;
};

/// A protocol capability
type Protocol = table {
    1: name fuchsia.component.name;
    2: as fuchsia.component.name; // optional
    3: type fuchsia.component.decl.DependencyType; // optional
    4: path string:fuchsia.component.MAX_PATH_LENGTH; // optional
};

/// A directory capability
type Directory = table {
    1: name fuchsia.component.name;
    2: as fuchsia.component.name; // optional
    3: type fuchsia.component.decl.DependencyType; // optional
    4: subdir string:fuchsia.component.MAX_PATH_LENGTH; // optional

    // the following fields are required if `to` contains a local component
    5: rights fuchsia.io.Rights;
    6: path string:fuchsia.component.MAX_PATH_LENGTH;
};

/// A storage capability
type Storage = table {
    1: name fuchsia.component.name;
    2: as fuchsia.component.name; // optional

    // required if `to` contains a local component
    3: path fuchsia.component.name;
};

/// A service capability
type Service = table {
    1: name fuchsia.component.name;
    2: as fuchsia.component.name; // optional

    // required if `to` contains a local component
    3: path string:fuchsia.component.MAX_PATH_LENGTH;
};

/// An event capability
type Event = table {
    1: name fuchsia.component.name;
    2: as fuchsia.component.name; // optional
    3: filter fuchsia.data.Dictionary;
};

/// Properties that may be set on a child when it is added to a realm
type ChildOptions = table {
    1: startup fuchsia.component.decl.StartupMode;
    2: environment fuchsia.component.name;
    3: on_terminate fuchsia.component.decl.OnTerminate;
};

const MAX_DIRECTORY_ENTRIES uint32 = 1024;

/// The contents of a directory that should be provided by the realm builder
/// server.
type DirectoryContents = resource struct {
    entries vector<DirectoryEntry>:MAX_DIRECTORY_ENTRIES;
};

type DirectoryEntry = resource struct {
    /// The path to the file. Valid examples include `foo.txt` and
    /// `foo/bar.json`.
    file_path fuchsia.component.name;

    /// The contents of the file.
    file_contents fuchsia.mem.Buffer;
};

protocol Realm {
    /// Adds a component to the realm.
    ///
    /// Errors:
    /// - `CHILD_ALREADY_EXISTS`: this realm already contains a child with the
    ///   given name.
    /// - `INVALID_MANIFEST_EXTENSION`: `url` ends with `.cmx`, and thus should
    ///   be used with `AddLegacyChild` instead of `AddChild`.
    /// - `DECL_NOT_FOUND`: The test package does not contain the component
    ///   declaration referenced by a relative URL.
    /// - `DECL_READ_ERROR`: Encountered an I/O error when attempting to read a
    ///   component declaration referenced by a relative URL from the test
    ///   package.
    /// - `BUILD_ALREADY_CALLED`: The `Builder.Build` function has been called
    ///   for this realm, and thus this `Realm` channel can no longer be used.
    AddChild(struct {
        /// The name of the child that is being added.
        name fuchsia.component.name;

        /// The component's URL.
        url fuchsia.url.Url;

        /// Additional properties for the child.
        options ChildOptions;
    }) -> (struct {}) error RealmBuilderError2;

    /// Adds a [legacy
    /// component](https://fuchsia.dev/fuchsia-src/concepts/components/v1) to
    /// the realm. When the component is launched, RealmBuilder will reach out
    /// to appmgr to assist with launching the component, and the component will
    /// be able to utilize all of the features of the legacy component
    /// framework. Note that _only_ protocol capabilities may be routed to this
    /// component. Capabilities of any other type (such as a directory) are
    /// unsupported for legacy components launched by RealmBuilder, and this
    /// legacy component should instead use the CMX features to access things
    /// such as storage.
    ///
    /// Errors:
    /// - `CHILD_ALREADY_EXISTS`: this realm already contains a child with the
    ///   given name.
    /// - `INVALID_MANIFEST_EXTENSION`: `url` does not end with `.cmx`, and thus
    ///   should be used with `AddChild` instead of `AddLegacyChild`.
    /// - `BUILD_ALREADY_CALLED`: The `Builder.Build` function has been called
    ///   for this realm, and thus this `Realm` channel can no longer be used.
    AddLegacyChild(struct {
        /// The name of the child that is being added.
        name fuchsia.component.name;

        /// The component's legacy URL (commonly ends with `.cmx`).
        legacy_url fuchsia.url.Url;

        /// Additional properties for the child.
        options ChildOptions;
    }) -> (struct {}) error RealmBuilderError2;

    /// Adds a component to this realm whose declaration is set to `decl`. When
    /// launched, the component will share the test package as its package
    /// directory, and may access any resources from it.
    ///
    /// Errors:
    /// - `CHILD_ALREADY_EXISTS`: this realm already contains a child with the
    ///   given name.
    /// - `INVALID_COMPONENT_DECL`: `decl` failed validation.
    /// - `BUILD_ALREADY_CALLED`: The `Builder.Build` function has been called
    ///   for this realm, and thus this `Realm` channel can no longer be used.
    AddChildFromDecl(struct {
        /// The name of the child that is being added.
        name fuchsia.component.name;

        /// The component's declaration.
        decl fuchsia.component.decl.Component;

        /// Additional properties for the child.
        options ChildOptions;
    }) -> (struct {}) error RealmBuilderError2;

    /// Adds a component to the realm whose implementation will be provided by
    /// the client. When this component should be started, the runner channel
    /// passed into `Build` will receive a start request for a component whose
    /// `ProgramDecl` contains the relative moniker from the root of the
    /// constructed realm for the child that is to be run under the `program`
    /// key `LOCAL_COMPONENT_NAME`.
    ///
    /// Errors:
    /// - `CHILD_ALREADY_EXISTS`: this realm already contains a child with the
    ///   given name.
    /// - `BUILD_ALREADY_CALLED`: The `Builder.Build` function has been called
    ///   for this realm, and thus this `Realm` channel can no longer be used.
    AddLocalChild(struct {
        /// The name of the child that is being added.
        name fuchsia.component.name;

        /// Additional properties for the child.
        options ChildOptions;
    }) -> (struct {}) error RealmBuilderError2;

    /// Adds a child realm which can be built with the client end of
    /// `child_realm`.
    ///
    /// Errors:
    /// - `CHILD_ALREADY_EXISTS`: this realm already contains a child with the
    ///   given name.
    /// - `BUILD_ALREADY_CALLED`: The `Builder.Build` function has been called
    ///   for this realm, and thus this `Realm` channel can no longer be used.
    AddChildRealm(resource struct {
        /// The name of the child realm that is being added.
        name fuchsia.component.name;

        /// Additional properties for the child.
        options ChildOptions;

        /// The server end of the `Realm` channel that will be used to build the
        /// sub-realm.
        child_realm server_end:Realm;
    }) -> (struct {}) error RealmBuilderError2;

    /// Returns the component decl for the given component. `name` must refer to
    /// a component that is one of the following:
    ///
    /// - A component with a local implementation
    /// - A legacy component
    /// - A component added with a relative URL
    /// - An automatically generated realm (ex: the root)
    ///
    /// Errors:
    /// - `NO_SUCH_CHILD`: This realm does not contain a child with the given
    ///   name.
    /// - `CHILD_DECL_NOT_VISIBLE`: The component decl cannot be fetched for
    ///   the referenced child, because the child was added to the realm using
    ///   an absolute (not-relative) and modern (not legacy) URL.
    /// - `BUILD_ALREADY_CALLED`: The `Builder.Build` function has been called
    ///   for this realm, and thus this `Realm` channel can no longer be used.
    GetComponentDecl(struct {
        /// The name of the component whose declaration is being retrieved.
        name fuchsia.component.name;
    }) -> (struct {
        component_decl fuchsia.component.decl.Component;
    }) error RealmBuilderError2;

    /// Replaces the component decl for the given component. `name` must
    /// refer to a component that is one of the following:
    ///
    /// - A component with a local implementation
    /// - A legacy component
    /// - A component added with a relative URL
    /// - An automatically generated realm (ex: the root)
    ///
    /// Errors:
    /// - `NO_SUCH_CHILD`: This realm does not contain a child with the given
    ///   name.
    /// - `CHILD_ALREADY_EXISTS`: The component whose decl is being replaced has
    ///   had a child added to it through realm builder with the same name as an
    ///   element in `component_decl.children`.
    /// - `CHILD_DECL_NOT_VISIBLE`: The component decl cannot be manipulated for
    ///   the referenced child, because the child was added to the realm using
    ///   an absolute (not relative) and modern (not legacy) URL.
    /// - `INVALID_COMPONENT_DECL`: `component_decl` failed validation.
    /// - `BUILD_ALREADY_CALLED`: The `Builder.Build` function has been called
    ///   for this realm, and thus this `Realm` channel can no longer be used.
    ReplaceComponentDecl(struct {
        /// The name of the component whose declaration is being replaced.
        name fuchsia.component.name;

        /// The new component declaration for `name`.
        component_decl fuchsia.component.decl.Component;
    }) -> (struct {}) error RealmBuilderError2;

    /// Returns the component decl for this realm.
    ///
    /// Errors:
    /// - `BUILD_ALREADY_CALLED`: The `Builder.Build` function has been called
    ///   for this realm, and thus this `Realm` channel can no longer be used.
    GetRealmDecl() -> (struct {
        component_decl fuchsia.component.decl.Component;
    }) error RealmBuilderError2;

    /// Replaces the component decl for this realm.
    ///
    /// Errors:
    /// - `INVALID_COMPONENT_DECL`: `component_decl` failed validation.
    /// - `BUILD_ALREADY_CALLED`: The `Builder.Build` function has been called
    ///   for this realm, and thus this `Realm` channel can no longer be used.
    ReplaceRealmDecl(struct {
        /// The new component declaration for this realm.
        component_decl fuchsia.component.decl.Component;
    }) -> (struct {}) error RealmBuilderError2;

    /// Mutates component manifests in the realm such that every component in
    /// `to` will have a valid capability route for each item in `capabilities`
    /// provided by `from`.
    ///
    /// Errors:
    /// - `NO_SUCH_SOURCE`: `from` references a non-existent child.
    /// - `NO_SUCH_TARGET`: `to` references a non-existent child.
    /// - `CAPABILITIES_EMPTY`: `capabilities` is empty.
    /// - `TARGETS_EMPTY`: `to` is empty.
    /// - `SOURCE_AND_TARGET_MATCH`: `from` is equal to one of the elements in
    ///   `to`.
    /// - `INVALID_COMPONENT_DECL`: The requested route caused one of the
    ///   involved manifests to fail validation.
    /// - `BUILD_ALREADY_CALLED`: The `Builder.Build` function has been called
    ///   for this realm, and thus this `Realm` channel can no longer be used.
    AddRoute(struct {
        /// The capabilities that are to be routed.
        capabilities vector<Capability2>:MAX;

        /// The location where the elements of `capabilities` are available.
        from fuchsia.component.decl.Ref;

        /// The locations that should be able to access `capabilities`.
        to vector<fuchsia.component.decl.Ref>:MAX;
    }) -> (struct {}) error RealmBuilderError2;

    /// Offers a directory capability to a component in this realm. The
    /// directory will be read-only (i.e. have `r*` rights), and will have the
    /// contents described in `directory_contents`.
    ///
    /// Errors:
    /// - `NO_SUCH_TARGET`: `offer-to` references a non-existent child.
    /// - `BUILD_ALREADY_CALLED`: The `Builder.Build` function has been called
    ///   for this realm, and thus this `Realm` channel can no longer be used.
    ReadOnlyDirectory(resource struct {
        /// The name of the directory capability.
        name fuchsia.component.name;

        /// The target that this directory will be offered to.
        to vector<fuchsia.component.decl.Ref>:MAX;

        /// The contents of the directory.
        directory_contents DirectoryContents;
    }) -> (struct {}) error RealmBuilderError2;
};
