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

using fuchsia.io;
using zx;

/// 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 interfaces.
    url component_url;

    /// The arguments to be provided to the component.
    arguments vector<string:MAX>:<MAX, 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 interface request for a Directory that points at the "svc/" subdirectory
    /// of the component's outgoing directory channel. The channel CANNOT be used
    /// to connect to other directories (such as "debug/" or "diagnostics/") the component
    /// publishes in their outgoing directory.
    @available(replaced=10)
    directory_request zx.Handle:<CHANNEL, optional>;
    @available(added=10)
    directory_request server_end:<fuchsia.io.Directory, optional>;

    /// 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.
    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:<ServiceProvider, optional>;

    /// A channel to the directory hosting the services in `names`.
    @available(replaced=10)
    host_directory zx.Handle:<CHANNEL, optional>;
    @available(added=10)
    host_directory client_end:<fuchsia.io.Directory, optional>;
};

/// An interface 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 an `ComponentController`'s interface is
    /// requested, the component instance is killed when the interface is closed.
    strict CreateComponent(resource struct {
        launch_info LaunchInfo;
        controller server_end:<ComponentController, optional>;
    });
};
