// Copyright 2023 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;

using fuchsia.component.sandbox;
using fuchsia.io;
using fuchsia.process;

@available(added=14)
const MAX_NAMESPACE_COUNT uint32 = 32;

@available(added=14, replaced=18)
closed protocol Controller {
    /// Start the component, optionally providing additional handles to be given
    /// to the component. Returns INSTANCE_ALREADY_RUNNING if the instance is
    /// currently running.
    strict Start(resource struct {
        args StartChildArgs;
        execution_controller server_end:ExecutionController;
    }) -> () error Error;

    /// Returns true if this instance is currently running.
    strict IsStarted() -> (resource struct {
        is_started bool;
    }) error Error;
};

/// A protocol used to operate on a component.
///
/// One may get access to a `Controller` when creating a component with the
/// `Realm.CreateChild` method. You may also obtain a `Controller` for an
/// existing child component with the `Realm.OpenController` method.
@available(added=18)
open protocol Controller {
    /// Start the component, optionally providing additional handles to be given
    /// to the component. Returns INSTANCE_ALREADY_RUNNING if the instance is
    /// currently running.
    flexible Start(resource struct {
        args StartChildArgs;
        execution_controller server_end:ExecutionController;
    }) -> () error Error;

    /// Returns true if this instance is currently running.
    flexible IsStarted() -> (resource struct {
        is_started bool;
    }) error Error;

    /// Returns the dictionary containing the component's exposed capabilities.
    @available(added=HEAD)
    flexible GetExposedDictionary(resource struct {
        dictionary server_end:fuchsia.component.sandbox.Dictionary;
    }) -> () error Error;
};

@available(added=14)
type StartChildArgs = resource table {
    /// The numbered handles to pass to the component instance.
    ///
    /// If the runner for the component does not support the numbered handles it
    /// is expected to close the handles.
    ///
    /// If set, the values given here will override the handles given in
    /// CreateChildArgs.
    1: numbered_handles vector<fuchsia.process.HandleInfo>:MAX_HANDLE_COUNT;

    /// The namespace generated by component manager will be extended to include
    /// any namespace entries listed here before being given to the component's
    /// runner.
    ///
    /// If there are any conflicting entries, an error will occur when starting
    /// the component.
    2: namespace_entries vector<NamespaceEntry>:MAX_NAMESPACE_COUNT;

    /// A dictionary that contains extra capabilities for the component instance.
    @available(added=HEAD)
    3: dictionary client_end:fuchsia.component.sandbox.Dictionary;
};

@available(added=14, replaced=18)
closed protocol ExecutionController {
    /// Initiates a stop action on this component. Once complete, OnStop will be
    /// called with the stopped payload.
    ///
    /// Note that a component may stop running on its own at any time, so it is
    /// possible for `OnStop` to be received before `Stop` is called.
    strict Stop();

    /// When the child is stopped due to `Stop` being called, the child exiting
    /// on its own, or for any other reason, `OnStop` is called and then this
    /// channel is closed.
    strict -> OnStop(struct {
        stopped_payload StoppedPayload;
    });
};
@available(added=18)
open protocol ExecutionController {
    /// Initiates a stop action on this component. Once complete, OnStop will be
    /// called with the stopped payload.
    ///
    /// Note that a component may stop running on its own at any time, so it is
    /// possible for `OnStop` to be received before `Stop` is called.
    flexible Stop();

    /// When the child is stopped due to `Stop` being called, the child exiting
    /// on its own, or for any other reason, `OnStop` is called and then this
    /// channel is closed.
    flexible -> OnStop(struct {
        stopped_payload StoppedPayload;
    });
};

/// A single component namespace entry, which describes a namespace mount point
/// (`path`) and the directory backing it (`directory`). This type is usually
/// composed inside a vector.  See `ComponentStartInfo.ns` for more details.
@available(added=14)
type NamespaceEntry = resource table {
    /// The mount point for the directory, including a
    /// leading slash. For example: "/pkg", "/svc", or "/config/data".
    1: path string:MAX_PATH_LENGTH;

    /// The directory mounted at the above `path`.
    2: directory client_end:fuchsia.io.Directory;
};
