// 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.
type Buffer = resource struct {
    /// The vmo.
    vmo zx.Handle:VMO;

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

type TerminationReason = strict enum {
    // 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;
};

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

    // Decouples the lifetime of the component from this controller.
    //
    // After calling `Detach`, the component will not be implicitly killed when
    // this protocol is closed.
    strict 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.
    strict -> OnTerminated(struct {
        return_code int64;
        termination_reason TerminationReason;
    });

    // 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.
    strict -> OnDirectoryReady();
};

// A protocol for controlling an environment.
//
// Closing this protocol implicitly kills the controlled environment unless
// the `Detach` method has been called.
//
// If the environment is destroyed, this protocol will be closed.
//
// Typically obtained via `Environment.CreateNestedEnvironment`.
closed 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.
    strict Kill() -> ();

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

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

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

type EnvironmentOptions = struct {
    // True if this environment should inherit services provided by the
    // parent environment.
    inherit_parent_services bool;
    // 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.
    allow_parent_runners bool;
    // 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.
    kill_on_oom bool;
    // True if "persistent" storage requested by components in this environment should not actually
    // be persistent, and instead be deleted when this environment is killed.
    delete_storage_on_death bool;
};

// A protocol for managing a set of applications.
//
// Applications run inside environments, which provide ambient services and
// support for their lifecycle.
@discoverable
closed 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` client endpoint 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.
    strict CreateNestedEnvironment(resource struct {
        environment server_end:Environment;
        controller server_end:EnvironmentController;
        label string;
        additional_services box<ServiceList>;
        options EnvironmentOptions;
    });

    // 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`.
    strict GetLauncher(resource struct {
        launcher server_end:Launcher;
    });

    // Gets a superset of services provided by this environment's
    // `host_directory`.
    strict GetServices(resource struct {
        services server_end:Provider;
    });

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

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

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

// A protocol for providing a job handle. Instances of this protocol are
// created in the context of an already-identified realm, so there is no need
// to explicitly identify the realm below.
@discoverable
closed protocol JobProvider {
    // Gets the root job associated with the realm.
    strict GetJob() -> (resource struct {
        job zx.Handle:JOB;
    });
};

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

    // The handles for the file descriptor (e.g., a channel).
    handle0 zx.Handle:optional;
    handle1 zx.Handle:optional;
    handle2 zx.Handle:optional;
};

// Information used to create an instance of a component and obtain
// services from it.
type LaunchInfo = resource struct {
    // 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 protocols.
    url string;

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

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

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

    // The protocol request for a Directory that is passed through to the
    // component and arrives in the component as its `directory_request`
    // protocol request.
    directory_request zx.Handle:<CHANNEL, optional>;

    // A custom namespace that can be appended to the namespace of the 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.
    flat_namespace box<FlatNamespace>;

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

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

    // A service provider to get the services listed in `names` from.
    provider client_end:<Provider, optional>;

    // A channel to the directory hosting the services in `names`.
    // TODO(https://fxbug.dev/42106217): Support `host_directory` for CreateComponent and deprecate
    // `provider`.
    host_directory zx.Handle:<CHANNEL, optional>;
};

// A protocol for creating component instances.
//
// Typically obtained via `Environment.GetLauncher`.
@discoverable
closed 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 provided, the component instance is killed when
    // the `ComponentController` client endpoint is closed.
    strict CreateComponent(resource struct {
        launch_info LaunchInfo;
        controller server_end:<ComponentController, optional>;
    });
};

// A protocol for loading from packages.
@discoverable
closed protocol Loader {
    // LoadUrl a package by url.
    strict LoadUrl(struct {
        url string;
    }) -> (resource struct {
        package box<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.
type StartupInfo = resource struct {
    // The launch info for the to start.
    launch_info LaunchInfo;

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

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

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

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

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

// A binary representation of a component.
//
// Typically provided to `Runner.StartComponent` when starting a
// component.
type Package = resource struct {
    // 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.
    data box<Buffer>;

    // 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.
    directory zx.Handle:<CHANNEL, optional>;

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

// A protocol for running components.
//
// Typically exposed by components that provide execution environments for
// particular classes of programs. For example, the Dart virtual machine exposes
// this protocol to run Dart programs.
@discoverable
closed 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` protocol request typically originates from the
    // `Launcher.CreateComponent` message that caused this
    // component to be started.
    strict StartComponent(resource struct {
        package Package;
        startup_info StartupInfo;
        controller server_end:<ComponentController, optional>;
    });
};

// A protocol through which a client may request services from a host.
// Instances of this protocol 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 protocol is deprecated.  Services should be published as directory
// entries instead, just like files.
// TODO(https://fxbug.dev/42106217): Point to the FIDL protocol for file I/O once RIO is migrated.
closed 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`.
    strict ConnectToService(resource struct {
        service_name string;
        channel zx.Handle:CHANNEL;
    });
};
