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

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

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

    /// 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 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.
    GetFastboot(
        string:fuchsia.device.DEVICE_NAME_MAX? target,
        request<Fastboot> fastboot) -> () error FastbootError;

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