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

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

[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;
};
