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