// Copyright 2022 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.component;
using fuchsia.component.decl;

/// Routing error for a particular capability.
type RouteError = table {
    /// A human-readable explanation of the routing error.
    1: summary string:MAX;
};

type DeclType = flexible enum {
    /// The capability comes from a `use` declaration in the component's manifest.
    /// It will be available in the namespace of the component instance.
    USE = 1;

    /// The capability comes from an `expose` declaration in the component's manifest.
    EXPOSE = 2;

    /// A capability that could be either a `use` or `expose` declaration. Used
    /// in inputs only, for fuzzy matching.
    ANY = 3;
};

/// Routing result for a particular capability.
type RouteReport = table {
    /// The capability whose routing was attempted.
    1: capability string:MAX;

    /// Type of capability declaration
    2: decl_type DeclType;

    /// Describes the error that occurred from routing this capability.
    /// This field is not present if routing succeeded.
    3: error RouteError;

    /// The moniker of the source component.
    @available(added=12)
    4: source_moniker string:MAX;

    /// Metadata about the instances in a service. Populated only for aggregated services.
    @available(added=12)
    5: service_instances vector<ServiceInstance>:MAX;

    /// The requested level of availability of the capability.
    @available(added=HEAD)
    6: availability fuchsia.component.decl.Availability;
};

/// Metadata about a service instance.
@available(added=12)
type ServiceInstance = table {
    /// The name of the service instance in this service directory.
    1: instance_name string:MAX;

    /// The name of the component that serves the service instance,
    /// including the collection name if the component is a child.
    2: child_name string:MAX;

    /// The name of the service instance as exposed by the child.
    3: child_instance_name string:MAX;
};

/// A capability in a target component to route to the source.
@available(added=12)
type RouteTarget = struct {
    /// The capability name to match (this is not the path). Supports fuzzy
    /// matching by substring.
    name fuchsia.component.name;
    /// Whether the capability is a `use`d by the component or `expose`d
    /// from it.
    decl_type DeclType;
};

/// Errors for RouteValidator
@available(added=12)
type RouteValidatorError = flexible enum {
    /// An unexpected error occurred.
    INTERNAL = 1;
    /// At least one argument had an invalid format.
    INVALID_ARGUMENTS = 2;
    /// The component instance was not found.
    INSTANCE_NOT_FOUND = 3;
    /// The component instance was not resolved.
    INSTANCE_NOT_RESOLVED = 4;
};

@discoverable
closed protocol RouteValidator {
    /// Routes all incoming and exposed capabilities of a component identified by the given
    /// moniker. If the routing failed, an error is returned in the response.
    /// This function may cause components to be resolved.
    ///
    /// Errors:
    /// * INVALID_ARGUMENTS: The given moniker is not valid.
    /// * INSTANCE_NOT_FOUND: No instance was found matching the given moniker.
    strict Validate(struct {
        moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
    }) -> (struct {
        reports vector<RouteReport>:MAX;
    }) error fuchsia.component.Error;

    /// Routes a component's used or exposed capabilities, and returns
    /// information about them.
    ///
    /// If `targets` is empty, returns results for all the component's used and
    /// exposed capabilities. Otherwise, returns only results for capabilities
    /// specified in `targets`.
    ///
    /// This method only supports routing namespace capabilities (protocols,
    /// directories, services, and storage).
    ///
    /// Errors:
    /// * INVALID_ARGUMENTS: The given moniker or name is not valid, or `name`
    ///   is not a namespace capability.
    /// * INSTANCE_NOT_FOUND: No instance was found matching the given moniker.
    /// * RESOURCE_NOT_FOUND: No capability was found matching one of the given names.
    @available(added=12)
    strict Route(struct {
        /// The target component with the capability to route.
        moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
        /// The target capabilites to route (i.e., uses or exposes)
        targets vector<RouteTarget>:MAX;
    }) -> (struct {
        reports vector<RouteReport>:MAX;
    }) error RouteValidatorError;
};
