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