// Copyright 2025 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.
@available(added=HEAD)
library fuchsia.component.runtime;

using fuchsia.component.decl;
using fuchsia.unknown;
using fuchsia.io;
using zx;
using fuchsia.component.sandbox;

@available(added=HEAD)
const MAX_DATA_LENGTH uint32 = 8192;

/// A runtime capability in the component framework. These are the fundamental
/// types used by component manager to implement capability routing and access
/// control.
///
/// Each of these client ends is a reference to an object owned by component
/// manager.
@available(added=HEAD)
type Capability = flexible resource union {
    1: connector client_end:Connector;
    2: dir_connector client_end:DirConnector;
    3: dictionary client_end:Dictionary;
    4: data Data;
    5: connector_router client_end:ConnectorRouter;
    6: dir_connector_router client_end:DirConnectorRouter;
    7: dictionary_router client_end:DictionaryRouter;
    8: data_router client_end:DataRouter;
};

/// A `Connector` represents the sending end of a connection to a capability. A
/// `Connector` presents as a service node when inserted into a
/// `fuchsia.io.Directory`.
@available(added=HEAD)
open protocol Connector {
    compose fuchsia.unknown.Cloneable;

    /// Sends a channel to the `Receiver` associated with this `Connector`.
    flexible Connect(resource struct {
        channel zx.Handle:CHANNEL;
    });
};

/// A `Receiver` represents the receiving end of a connection to a capability.
@available(added=HEAD)
open protocol Receiver {
    /// `Receive` will be called by component manager whenever an new handle has
    /// been given to any `Connector` associated with this `Receiver`.
    flexible Receive(resource struct {
        channel zx.Handle:CHANNEL;
    });
};

/// A `DirConnector` represents the sending end of a connection to a capability.
/// A `DirConnector` presents as a directory node when inserted into a
/// `fuchsia.io.Directory`.
@available(added=HEAD)
open protocol DirConnector {
    compose fuchsia.unknown.Cloneable;

    /// Sends a channel to the `DirReceiver` associated with this `DirConnector`.
    flexible Connect(resource struct {
        channel server_end:fuchsia.io.Directory;
    });
};

/// A `DirReceiver` represents the receiving end of a connection to a
/// capability.
@available(added=HEAD)
open protocol DirReceiver {
    /// `Receive` will be called by component manager whenever a new handle has
    /// been given to any `DirConnector` associated with this `DirReceiver`.
    flexible Receive(resource struct {
        channel server_end:fuchsia.io.Directory;
    });
};

/// A `Dictionary` is a bundle of named runtime capabilities.
@available(added=HEAD)
open protocol Dictionary {
    compose fuchsia.unknown.Cloneable;

    /// Inserts a new `Capability` into this `Dictionary` under the name `key`.
    /// Overwrites any existing entry.
    ///
    /// The server end associated with the provided client end must be owned by
    /// component manager.
    flexible Insert(resource struct {
        key fuchsia.component.decl.name;
        capability Capability;
    });

    /// Returns a clone of the `Capability` named `key` in this dictionary, if
    /// that capability both exists and can be cloned.
    flexible Get(resource struct {
        key fuchsia.component.decl.name;
    }) -> (resource struct {
        capability Capability:<optional>;
    });

    /// Removes the `Capability` named `key` from this dictionary and returns
    /// it, if that capability exists.
    flexible Remove(resource struct {
        key fuchsia.component.decl.name;
    }) -> (resource struct {
        capability Capability:<optional>;
    });

    /// Opens an iterator which can be used to iterate over the keys of this
    /// dictionary.
    flexible IterateKeys(resource struct {
        key_iterator server_end:DictionaryKeyIterator;
    });

    /// Exports this dictionary for use in a
    /// `fuchsia.component.Realm/CreateChild` call.
    flexible LegacyExport() -> (resource struct {
        dictionary_ref fuchsia.component.sandbox.DictionaryRef;
    });
};

@available(added=HEAD)
open protocol DictionaryKeyIterator {
    /// Returns the next set of keys in this dictionary. Returns an empty vector
    /// when there are no more keys to iterate.
    flexible GetNext() -> (struct {
        keys vector<fuchsia.component.decl.name>:MAX;
    });
};

/// Static data which may be put in a dictionary. This is useful for setting
/// values in the metadata of a `RouteRequest`.
@available(added=HEAD)
type Data = flexible union {
    1: bytes vector<byte>:MAX_DATA_LENGTH;
    2: string string:MAX_DATA_LENGTH;
    3: int64 int64;
    4: uint64 uint64;
};

/// A factory for `Connector` capabilities.
@available(added=HEAD)
open protocol ConnectorRouter {
    compose fuchsia.unknown.Cloneable;

    /// Attempts to produce a `Connector` capability from this
    /// `ConnectorRouter`. This will return:
    ///
    /// - A `Connector` if the operation is successful.
    /// - An empty value if there is no issue found but the capability is not
    ///   being provided (for example, an optional route ended in an offer from
    ///   void).
    /// - An error, if the operation failed.
    flexible Route(resource struct {
        request RouteRequest;
        connector_server_end server_end:<Connector>;
    }) -> (resource struct {
        response RouterResponse;
    }) error RouterError;
};

/// A factory for `DirConnector` capabilities.
@available(added=HEAD)
open protocol DirConnectorRouter {
    compose fuchsia.unknown.Cloneable;

    /// Attempts to produce a `DirConnector` capability from this
    /// `DirConnectorRouter`. This will return:
    ///
    /// - A `DirConnector` if the operation is successful.
    /// - An empty value if there is no issue found but the capability is not
    ///   being provided (for example, an optional route ended in an offer from
    ///   void).
    /// - An error, if the operation failed.
    flexible Route(resource struct {
        request RouteRequest;
        dir_connector_server_end server_end:<DirConnector>;
    }) -> (resource struct {
        response RouterResponse;
    }) error RouterError;
};

/// A factory for `Dictionary` capabilities.
@available(added=HEAD)
open protocol DictionaryRouter {
    compose fuchsia.unknown.Cloneable;

    /// Attempts to produce a `Dictionary` capability from this
    /// `DictionaryRouter`. This will return:
    ///
    /// - A `Dictionary` if the operation is successful.
    /// - An empty value if there is no issue found but the capability is not
    ///   being provided (for example, an optional route ended in an offer from
    ///   void).
    /// - An error, if the operation failed.
    flexible Route(resource struct {
        request RouteRequest;
        dictionary_server_end server_end:<Dictionary>;
    }) -> (resource struct {
        response RouterResponse;
    }) error RouterError;
};

/// A factory for `Data` capabilities.
@available(added=HEAD)
open protocol DataRouter {
    compose fuchsia.unknown.Cloneable;

    /// Attempts to produce a `Data` capability from this
    /// `DataRouter`. This will return:
    ///
    /// - A `Data` value if the operation is successful.
    /// - An empty value if there is no issue found but the capability is not
    ///   being provided (for example, an optional route ended in an offer from
    ///   void).
    /// - An error, if the operation failed.
    flexible Route(resource struct {
        request RouteRequest;
    }) -> (resource struct {
        response RouterResponse;
        data Data:optional;
    }) error RouterError;
};

/// The error values returned when a route operation succeeds.
@available(added=HEAD)
type RouterResponse = flexible enum : uint32 {
    /// The server end has been connected to a valid object.
    SUCCESS = 1;

    /// The capability was marked as unavailable.
    UNAVAILABLE = 2;
};

/// The error values returned when a route operation fails.
@available(added=HEAD)
type RouterError = flexible enum : uint32 {
    /// The router failed to find the capability.
    NOT_FOUND = 1;

    /// The arguments provided to the function are invalid.
    INVALID_ARGS = 2;

    /// The operation is not supported.
    NOT_SUPPORTED = 3;

    /// An internal error occurred.
    INTERNAL = 4;

    /// An unknown error occurred.
    UNKNOWN = 5;
};

/// A token representing a component instance.
@available(added=HEAD)
type WeakInstanceToken = resource struct {
    token zx.Handle:EVENTPAIR;
};

/// Contains metadata on how to route a capability, and a token representing the
/// component that started the route.
///
/// Either both fields must be set, or neither.
@available(added=HEAD)
type RouteRequest = resource table {
    1: target WeakInstanceToken;
    2: metadata client_end:Dictionary;
};

/// The `CapabilityFactory` can be used to create new runtime capabilities.
@discoverable(server="platform")
@available(added=HEAD)
open protocol CapabilityFactory {
    flexible CreateConnector(resource struct {
        receiver_client_end client_end:Receiver;
        connector_server_end server_end:Connector;
    });

    flexible CreateDirConnector(resource struct {
        dir_receiver_client_end client_end:DirReceiver;
        dir_connector_server_end server_end:DirConnector;
    });

    flexible CreateDictionary(resource struct {
        dictionary_server_end server_end:Dictionary;
    });

    flexible CreateConnectorRouter(resource struct {
        router_client_end client_end:ConnectorRouter;
        router_server_end server_end:ConnectorRouter;
    });

    flexible CreateDirConnectorRouter(resource struct {
        router_client_end client_end:DirConnectorRouter;
        router_server_end server_end:DirConnectorRouter;
    });

    flexible CreateDictionaryRouter(resource struct {
        router_client_end client_end:DictionaryRouter;
        router_server_end server_end:DictionaryRouter;
    });

    flexible CreateDataRouter(resource struct {
        router_client_end client_end:DataRouter;
        router_server_end server_end:DataRouter;
    });
};
