// 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.
@available(added=7)
library fuchsia.component.test;

using fuchsia.component;
using fuchsia.component.config;
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;
    }) -> (struct {}) error RealmBuilderError;

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

/// 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 RealmBuilderError = 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;

    /// The component does not have a config schema defined. Attempting to
    /// set a config value is not allowed.
    NO_CONFIG_SCHEMA = 18;

    /// The component's config schema does not have a field with that name.
    NO_SUCH_CONFIG_FIELD = 19;

    /// A config value is invalid. This may mean a type mismatch or an issue
    /// with constraints like string/vector length.
    CONFIG_VALUE_INVALID = 20;
};

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 RealmBuilderError;
};

/// 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 Capability = flexible union {
    1: protocol Protocol;
    2: directory Directory;
    3: storage Storage;
    4: service Service;
    5: event Event;
};

/// A protocol capability
type Protocol = table {
    /// The name of the capability. This is usually the name of the FIDL
    /// protocol, e.g. `fuchsia.logger.LogSink`. If path is not set, the
    /// protocol will be installed in a target component's namespace at
    // `/svc/{name}`.
    1: name fuchsia.component.name;

    /// A rename of the capability, which can be set when routing to another
    // component. This field is optional.
    2: as fuchsia.component.name;

    /// For information on this type, see
    /// https://fuchsia.dev/go/components/declaration#DependencyType.
    /// This field is optional and defaults to `STRONG`.
    3: type fuchsia.component.decl.DependencyType;

    /// Override the path in which the protocol is installed. Instead of
    /// `/svc/{name}`, this value will be used. Path should begin with a
    /// leading slash and omit a trailing slash, e.g.
    /// `/foo/fuchsia.logger.LogSink`. This field is optional.
    4: path string:fuchsia.component.MAX_PATH_LENGTH;
};

/// A directory capability.
type Directory = table {
    /// The name of the capability. This is not the path of the directory.
    /// Instead it is a name used for routing.
    1: name fuchsia.component.name;

    /// A rename of the capability, which can be set when routing to another
    // component. This field is optional.
    2: as fuchsia.component.name;

    /// For information on this type, see
    /// https://fuchsia.dev/go/components/declaration#DependencyType.
    /// This field is optional and defaults to `STRONG`.
    3: type fuchsia.component.decl.DependencyType;

    /// The subdirectory of this directory to offer instead of the root. For
    /// example, if you set `bar/baz` as the subdir of `foo`, then `bar/baz`
    /// will be the root of the target's `foo`. This field is optional.
    4: subdir string:fuchsia.component.MAX_PATH_LENGTH;

    /// The maximum rights that can be set by a component using this directory.
    /// This field is required if it is being routed to a local component,
    /// otherwise, it is optional.
    5: rights fuchsia.io.Rights;

    /// The path in which to install the directory. The path should have a
    /// leading slash but no trailing slash, e.g. `/config/data`. This field
    /// is required.
    6: path string:fuchsia.component.MAX_PATH_LENGTH;
};

/// A storage capability
type Storage = table {
    /// The name of the capability. This is not the path of the directory.
    /// Instead it is a name used for routing.
    1: name fuchsia.component.name;

    /// A rename of the capability, which can be set when routing to another
    // component. This field is optional.
    2: as fuchsia.component.name;

    /// The path in which to install the directory. The path should have a
    /// leading slash but no trailing slash, e.g. `/config/data`. This field
    /// is required.
    3: path fuchsia.component.name;
};

/// A service capability
type Service = table {
    /// The name of the capability. This is usually the name of the FIDL
    /// service, e.g. `fuchsia.echo.EchoService`. If path is not set, the
    /// service will be installed in a target component's namespace at
    // `/svc/{name}`.
    1: name fuchsia.component.name;

    /// A rename of the capability, which can be set when routing to another
    // component. This field is optional.
    2: as fuchsia.component.name;

    /// Override the path in which the service is installed. Instead of
    /// `/svc/{name}`, this value will be used. Path should begin with a
    /// leading slash and omit a trailing slash, e.g.
    /// `/foo/fuchsia.echo.EchoService`. This field is optional.
    3: path string:fuchsia.component.MAX_PATH_LENGTH;
};

/// An event capability
type Event = table {
    /// The name of the capability.
    1: name fuchsia.component.name;

    /// A rename of the capability, which can be set when routing to another
    // component. This field is optional.
    2: as fuchsia.component.name;

    /// A filter to apply on the event.
    3: filter fuchsia.data.Dictionary;
};

/// Properties that may be set on a child when it is added to a realm.
type ChildOptions = table {
    /// For information on this type, see
    /// https://fuchsia.dev/go/components/declaration#StartupMode.
    /// Defaults to `LAZY`.
    1: startup fuchsia.component.decl.StartupMode;

    /// Specify a custom environment for the child to run under.
    2: environment fuchsia.component.name;

    /// For information on this type, see
    /// https://fuchsia.dev/go/components/declaration#OnTerminate.
    /// Defaults to `NONE`.
    3: on_terminate fuchsia.component.decl.OnTerminate;
};

/// Maximum number of entries allowed in one call of `Realm.ReadOnlyDirectory`.
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;
};

/// An entry in a directory.
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.child_name;

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

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

    /// 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.child_name;

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

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

    /// 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.child_name;

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

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

    /// 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.child_name;

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

    /// 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 RealmBuilderError;

    /// 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.child_name;
    }) -> (struct {
        component_decl fuchsia.component.decl.Component;
    }) error RealmBuilderError;

    /// 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.child_name;

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

    /// 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 RealmBuilderError;

    /// 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 RealmBuilderError;

    /// 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<Capability>: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 RealmBuilderError;

    /// 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 RealmBuilderError;

    /// Replaces the configuration value for a field specified by `key`.
    /// The component specified should have a config schema with this field.
    /// The value must conform to all constraints as defined by the schema.
    ///
    /// Errors:
    /// - `NO_CONFIG_SCHEMA`: component does not have a config schema
    /// - `NO_SUCH_CONFIG_FIELD`: `key` could not be found in component's config schema
    /// - `CONFIG_VALUE_INVALID`: `value` does not meet config schema constraints
    ReplaceConfigValue(struct {
        /// The name of the component whose config value is being replaced.
        name fuchsia.component.name;

        /// The key of the config field whose value is being replaced.
        key fuchsia.component.decl.ConfigKey;

        /// The config value being replaced.
        value fuchsia.component.config.ValueSpec;
    }) -> (struct {}) error RealmBuilderError;
};
