// Copyright 2019 The Chromium 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 test.fidlcodec.sys;

using zx;

// The goal of this file is to get a pretty big library.  It's a copy
// of fuchsia.sys and fuchsia.mem as of 26 April 2019.

/// A Buffer for data whose size is not necessarily a multiple of the page
/// size.
///
/// VMO objects have a physical size that is always a multiple of the page
/// size. As such, VMO alone cannot serve as a buffer for arbitrarly sized
/// data. `fuchsia.mem.Buffer` is a standard struct that aggregate the VMO
/// and its size.
resource struct Buffer {
    /// The vmo.
    zx.handle:VMO vmo;

    /// The size of the data in the vmo in bytes. This size must be smaller
    /// than the physical size of the vmo.
    uint64 size;
};

enum TerminationReason {
    // The channel closed without giving a termination reason.
    UNKNOWN = 0;
    // Component ran and exited with a given return_code.
    EXITED = 1;
    // The given URL given to launch was invalid.
    URL_INVALID = 2;
    // The requested package could not be found.
    PACKAGE_NOT_FOUND = 3;
    // An internal error happened during the launch process.
    INTERNAL_ERROR = 4;
    // Process creation failed.
    PROCESS_CREATION_ERROR = 5;
    // A Runner failed to start.
    RUNNER_FAILED = 6;
    // A Runner terminated while attempting to run a component.
    RUNNER_TERMINATED = 7;
    // Attempted to use an unsupported feature.
    UNSUPPORTED = 8;
};

// An interface for controlling components.
//
// Closing this interface implicitly kills the controlled component unless
// the `Detach` method has been called.
//
// If the component exits, this interface will be closed.
//
// Typically obtained via `Launcher.CreateComponent`.
protocol ComponentController {
    // Terminates the component.
    //
    // This ComponentController connection is closed when the component has
    // terminated.
    Kill();

    // Decouples the lifetime of the component from this controller.
    //
    // After calling `Detach`, the component will not be implicitly killed when
    // this interface is closed.
    Detach();

    // DEPRECATED: Use OnTerminated instead of Wait().
    // 3: Wait()

    // Event that is triggered when the component is terminated.
    //
    // This event provides the return code of the process and reason for
    // its termination. The return_code is only valid if the termination
    // reason is EXITED. If the termination reason is not EXITED, the
    // return code is guaranteed not to be 0.
    -> OnTerminated(int64 return_code, TerminationReason termination_reason);

    // Event that is triggered when the component's output directory is mounted.
    //
    // This event will not be triggered for every component, only those that
    // serve a directory over their PA_DIRECTORY_REQUEST handle.
    -> OnDirectoryReady();
};

// An interface for controlling an environment.
//
// Closing this interface implicitly kills the controlled environment unless
// the `Detach` method has been called.
//
// If the environment is destroyed, this interface will be closed.
//
// Typically obtained via `Environment.CreateNestedEnvironment`.
protocol EnvironmentController {
    // Terminates the environment.
    //
    // When an `Environment` is terminated, all applications launched
    // in the environment (and in all transitively nested environments) are also
    // killed.
    Kill() -> ();

    // Decouples the lifetime of the environment from this controller.
    //
    // After calling `Detach`, the environment will not be implicitly killed when
    // this interface is closed.
    Detach();

    // Event that is triggered when the environment is created.
    -> OnCreated();
};

// Maximum length for an environment label.
const uint32 LABEL_MAX_LENGTH = 32;

struct EnvironmentOptions {
    // True if this environment should inherit services provided by the
    // parent environment.
    bool inherit_parent_services;
    // True if components in this environment can share a runner provided
    // by the parent environment. If false, a new runner will be started
    // in this environment for components.
    bool allow_parent_runners;
    // True if this environment should be killed first in out of memory
    // situations by setting the ZX_PROP_JOB_KILL_ON_OOM property on this
    // environment's job.
    bool kill_on_oom;
    // True if "persistent" storage requested by components in this environment should not actually
    // be persistent, and instead be deleted when this environment is killed.
    bool delete_storage_on_death;
};

// An interface for managing a set of applications.
//
// Applications run inside environments, which provide ambient services and
// support for their lifecycle.
[Discoverable]
protocol Environment {
    // Creates a new environment nested inside this environment.
    //
    // When applications are created inside the nested environment using the
    // environment's `Launcher`, the environment requests the
    // environment services from `host_directory` before passing those services to
    // the newly created application in its `StartupInfo`.
    //
    // The `controller` can be used to control the lifecycle of the created
    // environment. Note that by default the environment will be killed
    // automatically when the `EnvironmentController`'s interface is closed. You
    // can use `EnvironmentController.Detach` to disable this behavior.
    //
    // `label` defines the new environment's label/name. It must be unique within
    // the parent environment (though not globally) and is used for isolating
    // separate environments. It can also be used for diagnostic purposes. The
    // label will be truncated if it is longer than `LABEL_MAX_LENGTH`.
    //
    // `additional_services`, which may be empty, contains a list of services
    // that the environment provides, which are hosted by
    // `additional_services.host_directory`. If `options.inherit_parent_services`
    // is false, `host_directory` must provide a `Loader` service if it wishes to
    // allow new components to be loaded in the new environment.
    //
    // `options` provides additional options, see `EnvironmentOptions` for
    // details.
    CreateNestedEnvironment(request<Environment> environment,
                            request<EnvironmentController> controller,
                            string label,
                            ServiceList? additional_services,
                            EnvironmentOptions options);

    // Gets the Launcher associated with this environment.
    //
    // Applications created using this application launcher will be given the
    // environment services provided by this environment's `host_directory`.
    GetLauncher(request<Launcher> launcher);

    // Gets a superset of services provided by this environment's
    // `host_directory`.
    GetServices(request<Provider> services);

    // Gets a superset of services provided by this environment's
    // `host_directory`.
    GetDirectory(zx.handle:CHANNEL directory_request);
};

resource struct FlatNamespace {
    // The mount point for each of the directories below.
    //
    // For example, ["/pkg", "/svc"].
    vector<string> paths;

    // The directories mounted at each path in the namespace.
    vector<zx.handle:CHANNEL> directories;
};

// An interface for providing a job handle. Instances of this interface are
// created in the context of an already-identified realm, so there is no need
// to explicitly identify the realm below.
[Discoverable]
protocol JobProvider {
    // Gets the root job associated with the realm.
    GetJob() -> (zx.handle:JOB job);
};

// An FDIO file descriptor.
// TODO(abarth): Use the real FDIO declaration once FDIO converts to FIDL2.
resource struct FileDescriptor {
    // The FDIO types of the handle (e.g., FA_FDIO_REMOTE).
    int32 type0;
    int32 type1;
    int32 type2;

    // The handles for the file descriptor (e.g., a channel).
    handle? handle0;
    handle? handle1;
    handle? handle2;
};

// Information used to create an instance of a component and obtain
// services from it.
resource struct LaunchInfo {
    // The location from which to retrieve this component.
    //
    // This field will probably be replaced with a stronger notion of identity,
    // such as an unforgeable token. This field is included in this iteration to
    // ease the transition from the previous component interfaces.
    string url;

    // The arguments to be provided to the component.
    vector<string>? arguments;

    // The file descriptor to use for stdout.
    //
    // If null, the component will use the default stdout for the environment.
    FileDescriptor? out;

    // The file descriptor to use for stderr.
    //
    // If null, the component will use the default stderr for the environment.
    FileDescriptor? err;

    // The interface request for a Directory that is passed through to the
    // component and arrives in the component as its `directory_request`
    // interface request.
    zx.handle:CHANNEL? directory_request;

    // A custom namespace that can be appended to the namespace generated by
    // appmgr and provided to this component.
    // Adding a mount point at standard paths like 'pkg' or 'svc' will be ignored.
    // HACK(alhaad): Adding mount points for deprecated default directories like
    // '/data' will override the default.
    FlatNamespace? flat_namespace;

    // A list of services to be added to this component's svc namespace. These
    // services are in addition to those coming from Environment.
    ServiceList? additional_services;
};

resource struct ServiceList {
    // A list of services that can be requested from `provider`.
    vector<string> names;

    // A service provider to get the services listed in `names` from.
    Provider? provider;

    // A channel to the directory hosting the services in `names`.
    // TODO(fxbug.dev/31262): Support `host_directory` for CreateComponent and deprecate
    // `provider`.
    zx.handle:CHANNEL? host_directory;
};

// An interface for creating component instances.
//
// Typically obtained via `Environment.GetLauncher`.
[Discoverable]
protocol Launcher {
    // Creates a new instance of the component described by `launch_info`.
    //
    // The component instance is created in the `Environment`
    // associated with this `Launcher`. When creating the component,
    // the environment requests the environment services for this component from
    // its `EnvironmentHost`.
    //
    // The `controller` can be used to control the lifecycle of the created
    // component instance. If an `ComponentController`'s interface is
    // requested, the component instance is killed when the interface is closed.
    CreateComponent(LaunchInfo launch_info,
                    request<ComponentController>? controller);
};

// An interface for loading from packages.
[Discoverable]
protocol Loader {
    // LoadUrl a package by url.
    LoadUrl(string url) -> (Package? package);
};

// Information given to components at startup.
//
// For ELF binaries, this information is provided in the initialization message
// given to libc by fuchsia.process.Launcher.
resource struct StartupInfo {
    // The launch info for the to start.
    LaunchInfo launch_info;

    // The namespace in which to run the component.
    FlatNamespace flat_namespace;

    // Key string value string map of the component's program metadata, obtained
    // from its component manifest.
    vector<ProgramMetadata>? program_metadata;

    // TODO(abarth): Add more fields to this struct relating to component and
    // environment identity.
};

// Program information about a component.
struct ProgramMetadata {
    // Key for program metadata pair. E.g. "binary" for an ELF binary component,
    // or "data" for a flutter/dart component.
    string key;

    // Value for program metadata pair. E.g. "bin/app" for a "binary" key, or
    // "data/foo" for a flutter/dart component.
    string value;
};

// A binary representation of a component.
//
// Typically provided to `Runner.StartComponent` when starting a
// component.
resource struct Package {
    // A read-only binary representation of the component. For example, if the
    // component is intended to run in the Dart virtual machine, this data might
    // contain a dartx package.
    Buffer? data;

    // A directory containing the contents of the package. For example, if the
    // component is stored in pkgfs, this directory will be the pkgfs directory
    // containing the package.
    zx.handle:CHANNEL? directory;

    // Resolved URL of the component. This is the url specified in startup_info
    // after following redirects and resolving relative paths.
    string resolved_url;
};

// An interface for running components.
//
// Typically exposed by components that provide execution environments for
// particular classes of programs. For example, the Dart virtual machine exposes
// this interface to run Dart programs.
[Discoverable]
protocol Runner {
    // Execute the given component.
    //
    // Upon startup, the component is to be given the information in
    // `startup_info`, but the mechanism by which the component receives that
    // information is up to the component runner.
    //
    // The `controller` interface request typically originates from the
    // `Launcher.CreateComponent` message that caused this
    // component to be started.
    StartComponent(Package package,
                   StartupInfo startup_info,
                   request<ComponentController>? controller);
};

// An interface through which a client may request services from a host.
// Instances of this interface are created within the context of an
// already-identified client and host pair, so there is no need to explicitly
// identify the client or host in the methods below.
//
// This interface is deprecated.  Services should be published as directory
// entries instead, just like files.
// TODO(fxbug.dev/31262): Point to the FIDL interface for file I/O once RIO is migrated.
protocol Provider {
    // Asks the host to provide the service identified by `service_name` through
    // the `channel` endpoint supplied by the caller. If the host is not willing
    // or able to provide the requested service, it should close the `channel`.
    ConnectToService(string service_name, zx.handle:CHANNEL channel);
};
