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

/// 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_capabilities| 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_capabilities| 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_capabilities| 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: Instance was not running and there was an error
    ///   starting it.
    BindChild(ChildRef child, request<fuchsia.io.Directory>
              exposed_capabilities) -> () error 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 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 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 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);
};
