// Copyright 2019 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.developer.bridge;
using fuchsia.developer.remotecontrol as rc;
using fuchsia.device;
using zx;

const uint8 MAX_SERVICE_NAME_SIZE = 255;

enum DaemonError {
    TARGET_CACHE_ERROR = 1;
    TARGET_STATE_ERROR = 2;
    RCS_CONNECTION_ERROR = 3;
    /// A generic timeout error.
    TIMEOUT = 4;

    /// When querying for an unspecified target, the cache was empty.
    TARGET_CACHE_EMPTY = 5;
    /// When querying for a target (specified or not), there were
    /// too many matches to be clear on which target was the intent
    /// of the query.
    TARGET_AMBIGUOUS = 6;
    /// When querying for a target, no matches were found.
    TARGET_NOT_FOUND = 7;
    /// When attempting to connect to RCS on a Fastboot device.
    TARGET_IN_FASTBOOT = 8;
    /// Fastboot device expected.
    NON_FASTBOOT_DEVICE = 9;
    /// When attempting to connect to a service that does not exist on the
    /// daemon.
    SERVICE_NOT_FOUND = 10;
    /// An error was encountered when attempting to open a service stream.
    SERVICE_OPEN_ERROR = 11;
    /// An error encountered when the daemon's service register is in a bad
    /// state internally. This is primarily caused by trying to open a service
    /// while the daaemon is actively shutting down, and should be extremely
    /// rare.
    BAD_SERVICE_REGISTER_STATE = 12;
    /// When attempting to connect to RCS on a Fastboot device.
    TARGET_IN_ZEDBOOT = 13;
};

[Discoverable]
protocol Daemon {
    /// Crashes the daemon. Primarily used for testing.
    Crash() -> ();

    /// Returns the input.
    EchoString(string:256 value) -> (string:256 response);

    /// Hang the daemon. Primarily used for testing.
    Hang() -> ();

    /// Lists targets by nodename.
    /// TODO(fxbug.dev/52798): Use an iterator instead of a limited vector.
    ListTargets(string:fuchsia.device.DEVICE_NAME_MAX value) -> (vector<Target>:512 response);

    /// Make the daemon exit.
    Quit() -> (bool success);

    /// Gets a remote control proxy for the given target.
    /// The target param expects an exact match with a target's
    /// nodename.
    ///
    /// If the target nodename is not included, this will return the remote
    /// control instance for the target iff there is only one target in the
    /// cache, else will return an error. If there are no targets in the cache,
    /// will wait until the client chooses to time out.
    GetRemoteControl(
        string:fuchsia.device.DEVICE_NAME_MAX? target,
        request<rc.RemoteControl> remote) -> () error DaemonError;

    /// Gets a fastboot proxy for the given target.
    /// The target param expects an exact match with a target's
    /// nodename.
    ///
    /// If the target nodename is not included, this will return the fastboot
    /// control instance for the target iff there is only one target in the
    /// cache, else will return an error. If there are no targets in the cache,
    /// will wait until the client chooses to time out.
    GetFastboot(
        string:fuchsia.device.DEVICE_NAME_MAX? target,
        request<Fastboot> fastboot) -> () error DaemonError;

    /// Attempts to get the SSH address for a given target.
    ///
    /// Waits for:
    /// 1.) A target of the given nodename to appear (if it hasn't already).
    /// 2.) For the target to have an SSH-friendly address.
    ///
    /// Returns:
    /// * First address found for the target that satisfies step 2.
    ///
    /// Errors:
    /// * Timeout error if steps 1 and 2 don't happen in time.
    /// * Cache error if a target has appeared but suddenly disappears before
    ///   running the function to completion.
    GetSshAddress(string:fuchsia.device.DEVICE_NAME_MAX? target, zx.duration timeout)
        -> (TargetAddrInfo ip) error DaemonError;

    // Retrieves version information about this daemon instance.
    GetVersionInfo() -> (VersionInfo info);

    /// Manually add a target that cannot be discovered via MDNS.
    AddTarget(TargetAddrInfo ip) -> () error DaemonError;

    /// Manually remove a target from the target list.
    ///
    /// If target_id doesn't match a device name, the daemon will try to interpret it as an IP.
    RemoveTarget(string:fuchsia.device.DEVICE_NAME_MAX target_id) -> (bool removed) error DaemonError;

    // Retrieves a hash of the current binary.
    GetHash() -> (string:64 response);

    /// Creates an iterator over diagnostics data. At present, this means cached log data.
    ///
    /// Note that there is some duplication in this API and the StreamDiagnostics API in RCS.
    /// This is because the surface for the daemon API needs to be slightly different:
    /// 1) It needs to accomodate specifying a target.
    /// 2) The error surface is accordingly slightly different.
    /// 3) The parameters surface is currently different (SNAPSHOT_RECENT_THEN_SUBSCRIBE has no meaning
    ///    in the diagnostics bridge) and have different evolution paths - for example, the daemon may
    ///    eventually support multi-target log streaming.
    StreamDiagnostics(
        string:fuchsia.device.DEVICE_NAME_MAX? target,
        DaemonDiagnosticsStreamParameters parameters,
        request<rc.ArchiveIterator> iterator)
        -> () error DiagnosticsStreamError;

    /// Gets a target proxy for the given target.
    /// The target param expects an exact match with a target's
    /// nodename.
    ///
    /// If the target nodename is not included, this will return the target
    /// control instance for the target iff there is only one target in the
    /// cache, else will return an error. If there are no targets in the cache,
    /// will wait until the client chooses to time out.
    GetTarget(
        string:fuchsia.device.DEVICE_NAME_MAX? target,
        request<TargetControl> target_controller) -> () error DaemonError;

    /// Connects to a deamon service.
    ///
    /// Takes a service name under which the channel will be connected (the
    /// caller is intended to know the type of the channel a priori).
    ///
    /// Developers are not intended to use this directly. Instead this should
    /// be invoked automatically through the FFX plugin/service framework.
    ///
    /// Again for emphasis: if you are a developer and you are invoking this
    /// function directly, you should reconsider your actions.
    ConnectToService(
        string:MAX_SERVICE_NAME_SIZE name,
        zx.handle:CHANNEL server_channel) -> () error DaemonError;
};
