// Copyright 2018 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.sys2;

using fuchsia.io;
using fuchsia.component;

/// A protocol used by a component instance to manage its own realm, such as for
/// binding to its children.
///
/// The component manager provides this service to components that use
/// `/svc/fuchsia.sys2.Realm`.
[Discoverable]
protocol Realm {
    /// Binds to a child component instance, causing it to start running if it
    /// is not already. When this function successfully returns, `child` is
    /// running and `exposed_dir` is bound to a directory that contains the
    /// capabilities which the child exposed to its realm via
    /// `ComponentDecl.exposes` (specified via "expose" declarations in the
    /// component’s manifest).
    ///
    /// `exposed_dir` is a valid channel as long as `child` is running. `child`
    /// will remain running until it either stops on its own, or `DestroyChild`
    /// causes the child instance to be destroyed.
    ///
    /// For example, if the child exposes a service `/svc/example.Echo` then
    /// `exposed_dir` will contain that service at that path.
    ///
    /// NOTE: `BindChild` does not support pipelining with `CreateChild`. If
    /// `BindChild` is called on an instance before `CreateChild` successfully
    /// returns, it may return `INSTANCE_NOT_FOUND`.
    ///
    /// Errors:
    /// - `INVALID_ARGUMENTS`: `child` is not a valid child reference.  -
    /// - `INSTANCE_NOT_FOUND`: `child` does not exist.
    /// - `INSTANCE_CANNOT_START`: `child` was not running and there was an error
    ///   starting it.
    /// - `INSTANCE_CANNOT_RESOLVE`: `child`'s component declaration failed to resolve.
    BindChild(ChildRef child,
              request<fuchsia.io.Directory> exposed_dir) -> () error fuchsia.component.Error;

    /// Creates a child component instance dynamically. When this function
    /// returns successfully, the instance exists, but it may not be running.
    ///
    /// The environment of the child instance is determined by the environment
    /// of the collection. `decl` must not set `environment`.
    ///
    /// Errors:
    /// - `INVALID_ARGUMENTS`: `collection` is not a valid reference or `child`
    ///   is not a valid declaration.
    /// - `COLLECTION_NOT_FOUND`: `collection` does not exist.
    /// - `INSTANCE_ALREADY_EXISTS`: `decl.name` already exists in `collection`.
    /// - `NO_SPACE`: Could not allocate storage for the new instance.
    CreateChild(CollectionRef collection, ChildDecl decl) -> () error fuchsia.component.Error;

    /// Destroys a dynamically-created component instance. When this function
    /// returns, the client should assume the instance no longer exists.
    /// However, some cleanup (such as stopping the component instance or
    /// freeing its storage) may be performed in the background after the
    /// function returns.
    ///
    /// Errors:
    /// - `INVALID_ARGUMENTS`: `child` is not a valid reference or does not refer
    ///   to a dynamic instance.
    /// - `INSTANCE_NOT_FOUND`: `child` does not exist.
    /// - `COLLECTION_NOT_FOUND`: `collection` does not exist.
    DestroyChild(ChildRef child) -> () error fuchsia.component.Error;

    /// Returns an iterator that lists all instances in a collection.
    ///
    /// NOTE: The results are not guaranteed to be consistent. Instances may be
    /// created or destroyed while the iterator is live, but those changes
    /// won't be observed by the iterator after this method returns.
    ///
    /// Errors:
    /// - `INVALID_ARGUMENTS`: `collection` is not a valid reference.
    /// - `COLLECTION_NOT_FOUND`: `collection` does not exist.
    ListChildren(CollectionRef collection, request<ChildIterator> iter) -> ()
        error fuchsia.component.Error;
};

/// A protocol to iterate over the list of children in a realm.
protocol ChildIterator {
    /// Advance the iterator and return the next batch of children.
    ///
    /// Returns a vector of `ChildRef`. Returns an empty vector when there are
    /// no more children.
    Next() -> (vector<ChildRef> children);
};
