// Copyright 2020 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.bluetooth.bredr;

using fuchsia.bluetooth;
using fuchsia.sys;

/// Information used to launch a profile component.
type LaunchInfo = table {
    /// Required. The location from which to retrieve this component.
    1: component_url fuchsia.sys.component_url;

    /// Optional. The arguments to be provided to the component.
    2: arguments vector<string:MAX>:MAX;
};

/// `PeerObserver` provides the integration test client with a way to validate the
/// behavior of a peer in the piconet.
/// Dropping `PeerObserver` will stop any subsequent updates for the peer.
protocol PeerObserver {
    /// The peer discovered the services of another peer in the piconet.
    ///
    /// + request `peer_id` The peer the service was found on.
    /// + request `protocol` Includes the ProtocolDescriptorList in the service record.
    /// + request `attributes` Contains all attributes requested from the search that
    ///                        are present on the peer record.
    ServiceFound(struct {
        peer_id fuchsia.bluetooth.PeerId;
        protocol ProtocolDescriptorList:optional;
        attributes vector<Attribute>:MAX_ATTRIBUTES;
    }) -> ();

    /// Called when a peer has connected to a service.
    ///
    /// + request `peer_id` The peer that connected to the service.
    /// + request `protocol` Contains the protocol list of the connection.
    PeerConnected(struct {
        peer_id fuchsia.bluetooth.PeerId;
        protocol ProtocolDescriptorList;
    }) -> ();

    /// Called when a component, launched by `MockPeer.LaunchProfile`, has terminated
    /// for any reason. `ComponentTerminated` does not provide information regarding
    /// why a component has terminated and should not be used for debugging.
    ///
    /// + request `component_url` URL of the component that has terminated.
    @deprecated("Replaced by component startup in ConnectProxy")
    ComponentTerminated(struct {
        component_url fuchsia.sys.component_url;
    }) -> ();
};

/// `MockPeer` provides an interface for managing the lifetime of a mock peer in the piconet.
/// Dropping `MockPeer` will unregister the peer from the Profile Test Server database.
///   - Any launched components associated with the mock peer will be terminated.
///   - Any actively connected `ProfileProxy` will be disconnected and dropped.
protocol MockPeer {
    /// Connect a channel to the [`fuchsia.bluetooth.bredr.Profile`] protocol for
    /// manipulation of the mock peer.
    ///
    /// It is valid to connect multiple proxies to a `MockPeer`.
    ///
    /// This parallels the current behavior of the bluetooth profile components.
    /// Specifically, profiles internally use the [`fuchsia.bluetooth.bredr.Profile`]
    /// service to register, search, and connect services. `ConnectProxy` provides a way
    /// for the test client to do the same for a given mock peer.
    ///
    /// If the `interface` is not connectable, it will be dropped with an epitaph
    /// signaling the failure.
    ///
    /// + request `interface` Interface to drive mock peer behavior.
    ConnectProxy(resource struct {
        interface server_end:Profile;
    }) -> ();

    /// Launch a profile specified by the `launch_info`.
    ///
    /// + request `launch_info` Information about the component to be launched.
    /// - response Acknowledgement when the profile has been launched, or an error code
    ///            if the profile could not be launched
    @deprecated("Use ConnectProxy instead")
    LaunchProfile(struct {
        launch_info LaunchInfo;
    }) -> (struct {}) error fuchsia.bluetooth.ErrorCode;
};

/// The `ProfileTest` interface should be used to validate behavior of Bluetooth Profiles
/// that use the [`fuchsia.bluetooth.bredr.Profile`] service.
///
/// The ProfileTest interface is used to create and manage fake peers.
/// A mock piconet is created in which registered peers can discover and interact with
/// each other.
@discoverable
protocol ProfileTest {
    /// Creates a new fake peer in the Profile Test Server database. An empty response is
    /// sent to indicate when registration is complete.
    ///
    /// Use the provided [`PeerObserver`] interface to observe behavior of the registered peer.
    /// Dropping the `observer` will cease the updates from the server for the associated peer.
    ///
    /// If registration is unsuccessful, the `peer` and `observer` will be closed.
    ///
    /// + request `peer_id` Identifier for the created peer.
    /// + request `peer` Handle that can be used to drive peer behavior using the
    ///                  [`fuchsia.blueooth.bredr.MockPeer`] interface.
    /// + request `observer` Relay for communicating updates from the mock peer.
    RegisterPeer(resource struct {
        peer_id fuchsia.bluetooth.PeerId;
        peer server_end:MockPeer;
        observer client_end:PeerObserver;
    }) -> ();
};
