// 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.ffx;
using fuchsia.device;
using fuchsia.net;
using fuchsia.buildinfo;
using fuchsia.developer.remotecontrol as rc;

type TargetIp = struct {
    ip fuchsia.net.IpAddress;
    scope_id uint32;
};

type TargetIpPort = struct {
    ip fuchsia.net.IpAddress;
    scope_id uint32;
    port uint16;
};

// TODO(awdavies): Add serial number.
type TargetAddrInfo = strict union {
    1: ip TargetIp;
    2: ip_port TargetIpPort;
};

// TODO(awdavies): Add more target states once they're more well defined.
type TargetState = strict enum {
    UNKNOWN = 1;
    DISCONNECTED = 2;
    PRODUCT = 3;
    FASTBOOT = 4;
    ZEDBOOT = 5;
};

// TODO(awdavies): Add more target types. Hardware? Product state?
type TargetType = strict enum {
    UNKNOWN = 1;
};

/// Address of the ssh host address from the perspective of the target.
type SshHostAddrInfo = struct {
    address string:256;
};

/// Current known state of the remote control
type RemoteControlState = strict enum {
    UP = 1;
    DOWN = 2;
    UNKNOWN = 3;
};

/// Interface fastboot is connected over.
type FastbootInterface = strict enum {
    USB = 0;
    UDP = 1;
    TCP = 2;
};

type TargetInfo = table {
    1: nodename string:fuchsia.device.DEVICE_NAME_MAX;
    2: addresses vector<TargetAddrInfo>:256;
    3: age_ms uint64;
    4: rcs_state RemoteControlState;
    5: target_type TargetType;
    6: target_state TargetState;
    // Contains the string used for the product in `fx set`, for example
    // `fx set core.x64` would make this value "core".
    7: product_config string:fuchsia.buildinfo.MAX_STRING_LENGTH;
    // Contains the string used for the board in `fx set`, for example
    // `fx set core.x64` would make this value "x64".
    8: board_config string:fuchsia.buildinfo.MAX_STRING_LENGTH;
    9: serial_number string:256;
    /// ssh_address is the preferred address to use to connect to the
    /// device over SSH, and will include a port number if a custom SSH
    /// port number has been set.
   10: ssh_address TargetAddrInfo;
   11: fastboot_interface FastbootInterface;
    /// The address of the ssh host as seen by the target.
   12: ssh_host_address SshHostAddrInfo;
};

type TargetRebootError = strict enum {
    /// Cannot reboot from fastboot to recovery.
    FASTBOOT_TO_RECOVERY = 1;
    /// There was an Overnet communication issue with the target.
    TARGET_COMMUNICATION = 2;
    /// There was a Fastboot protocol communication issue with the
    /// target.
    FASTBOOT_COMMUNICATION = 3;
    /// No netsvc address was found for the target when attempting
    /// to reboot from Zedboot.
    NETSVC_ADDRESS_NOT_FOUND = 4;
    /// Error when running a function through netsvc protocol.
    NETSVC_COMMUNICATION = 5;
};

type TargetRebootState = strict enum {
    PRODUCT = 1;
    BOOTLOADER = 2;
    RECOVERY = 3;
};

@discoverable
protocol TargetControl {
    @deprecated("Please use target collection -> target handle instead.")
    Reboot(struct {
        state TargetRebootState;
    }) -> (struct {}) error TargetRebootError;
};

/// An iterator for which the client handles calls to the `Next` function. When
/// a client calls `ListTargets` in the `TargetCollection` protocol, the targets
/// will be sent to the client via the `Next` function, with acknowledgements
/// sent via the responder to handle backpressure.
///
/// When there are no more targets to be sent to the client, an empty vector
/// will be sent as the last call to `Next`.
protocol TargetCollectionReader {
    Next(struct {
        entry vector<TargetInfo>:MAX;
    }) -> ();
};

/// A query for a Fuchsia target device. If empty when supplied to a method, will be
/// interpreted as requesting the first target to be seen on the network, or ALL
/// targets that have been seen on the network.
type TargetQuery = table {
    /// A string matcher is something that can match either the:
    /// - Target nodename (partial matches okay).
    /// - Target IP (any that have been seen).
    /// - Serial number (partial matches okay).
    ///
    /// IPv6 and IPv4 addresses are both acceptable queries. If the address being
    /// queried is ipv6 and includes a port number, the address (and
    /// scope id if present) must be enclosed in square brackets. Scope and port
    /// number are both optional, but may be present.
    ///
    /// If a port number is specified, it will match only with targets with
    /// that same port number (with no port set on the target being treated as
    /// the default ssh port, 22).
    ///
    /// Specifying 0 for the port will match specifically with hosts with
    /// no port specified.
    1: string_matcher string:255;
};

type OpenTargetError = strict enum {
    /// When querying for a target, an ambiguous query was received (one that
    /// matched multiple targets).
    QUERY_AMBIGUOUS = 1;
    /// No targets were able to match the query after waiting.
    TARGET_NOT_FOUND = 2;
};

type TargetConnectionError = strict enum {
    /// Permission was denied (from the public SSH key to the target).
    PERMISSION_DENIED = 1;
    /// SSH refused connection to the target.
    CONNECTION_REFUSED = 2;
    /// Hostname could not be resolved.
    UNKNOWN_NAME_OR_SERVICE = 3;
    /// Timed out trying to communicate with the target.
    TIMEOUT = 4;
    /// SSH Key verification could not proceed (usually a known_hosts issue).
    KEY_VERIFICATION_FAILURE = 5;
    /// There was no route to the specified host through SSH.
    NO_ROUTE_TO_HOST = 6;
    /// SSH could not reach the specified address.
    NETWORK_UNREACHABLE = 7;
    /// The address given was invalid for the target (likely containing a
    /// scope-ID that does not exist).
    INVALID_ARGUMENT = 8;
    /// An as-yet unseen error was encountered preventing connection to the
    /// device (user will need to check the logs).
    UNKNOWN_ERROR = 9;
    /// There was an error communicating via FIDL to the device. This happens
    /// after a connection has been established.
    FIDL_COMMUNICATION_ERROR = 10;
    /// An error was encountered while trying to knock a service in RCS. This
    /// means that RCS was unable to connect to a service in order to verify a
    /// FIDL channel can be established.
    RCS_CONNECTION_ERROR = 11;
    /// On attempting to 'knock' a service connection, the service dropped the
    /// channel prematurely, closing the connection.
    FAILED_TO_KNOCK_SERVICE = 12;
};

// TODO(https://fxbug.dev/94680): Migrate the method specifc error enums to use
// this type instead.
type TargetError = strict enum {
    /// The specified address does not exist within the target.
    ADDRESS_NOT_FOUND = 1;
};

/// Configuration options for adding a manual target.
type AddTargetConfig = table {
    /// Attempts to verify connection.
    1: verify_connection bool;
};

/// A protocol defining a collection of Fuchsia targets. This is used to inspect
/// and interact with fuchsia targets that the daemon has discovered.
@discoverable
protocol TargetCollection {
    /// Sends a list of all active targets in the collection. An active target
    /// is one that has responded over the network recently.
    ///
    /// An optional query string can be passed that will limit results to only
    /// targets whose metadata matches. Matching is limited to partial string
    /// matches via the target's nodename, serial number, or IP address.
    ///
    /// The client receives updates by handling calls to `Next` in the
    /// `TargetCollectionReader` protocol.
    ListTargets(resource struct {
        query TargetQuery;
        reader client_end:TargetCollectionReader;
    });

    /// Opens a target handle given the query matches exactly one
    /// target. If a target does not yet exist in the cache that matches the
    /// query, then this will hang until one is found. It is the caller's
    /// responsibility to time out if this call takes too long.
    OpenTarget(resource struct {
        query TargetQuery;
        target_handle server_end:Target;
    }) -> (struct {}) error OpenTargetError;

    /// Manually adds a target that cannot be discovered via mDNS. This target
    /// will be retained indefinitely, including across daemon restarts.
    ///
    /// If `verify_connection` is passed as true in the config, this will wait 
    /// until it is possible to establish a remote control service connection 
    /// to the target, or else will return an error detailing what went wrong 
    /// communicating with the Fuchsia device.
    ///
    /// Note: the client will be responsible for timing out against this method,
    /// as it will run for as long as the FIDL connection remains open. If the
    /// channel is closed prematurely, then the manually added target will be
    /// removed.
    ///
    /// If the channel to this call is dropped before the result is returned,
    /// it is possible to leak a persistent manual target, so later on the
    /// caller may need to invoke `RemoveTarget`.
    ///
    /// If `verify_connection` is passed as `false`, this function will return
    /// immediately, ignoring possible connection issues with the target.
    AddTarget(resource struct {
        ip TargetAddrInfo;
        config AddTargetConfig;
    }) -> (struct {}) error TargetConnectionError;

    /// Manually adds a target that cannot be discovered via mDNS. This target
    /// will be retained in the target collection until it establishes an RCS
    /// connection, or until the associated connection timeout has elapsed.
    AddEphemeralTarget(struct {
        ip TargetAddrInfo;
        connect_timeout_seconds uint64;
    }) -> ();

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

/// This is a handle to a target received from the target collection.
/// Not to be confused with the `TargetControl` protocol. This is exclusively
/// for use with the target collection service.
@discoverable
protocol Target {
    /// Returns:
    /// * As much information identifying the target as is currently available.
    Identity() -> (struct {
        target_info TargetInfo;
    });

    /// Gets the target SSH host pipe error logs for this target.
    ///
    /// Returns:
    /// * SSH host pipe error logs for the target. If there aren't any, will
    /// return an empty string.
    GetSshLogs() -> (struct {
        entry string:MAX;
    });

    /// Waits for an SSH address to become available on the target.
    ///
    /// Returns:
    /// * The first cached address viable for SSH. If there isn't one, will
    ///   wait until there is. It is the client's responsibility to handle
    ///   potential timeouts.
    GetSshAddress() -> (struct {
        address TargetAddrInfo;
    });

    /// Sets the preferred SSH address.
    ///
    /// If successful, then all subsequent interactions with the `Target` over
    /// SSH will leverage the provided `ip`. That is, any existing connection to
    /// target is severed and a new connection is established using the provided
    /// `ip`. Note that the specified address is not persisted across daemon
    /// version changes or restarts.
    ///
    /// This method is primarily useful in testing scenarios where a particular
    /// network interface should be used (e.g. other interfaces may be disabled
    /// during testing).
    ///
    /// Returns:
    /// * An error if the `ip` does not exist within the target. Otherwise,
    ///   nothing on success.
    SetPreferredSshAddress(struct {
        ip TargetIp;
    }) -> (struct {}) error TargetError;

    /// Clears an address that was previously configured using
    /// `SetPreferredSshAddress`.
    ///
    /// Any existing connection to the target is severed and a new connection is
    /// established. The newly selected address is chosen using the standard
    /// address selection logic.
    ///
    /// Returns:
    /// * Nothing on success.
    ClearPreferredSshAddress() -> ();

    /// Opens a connection to the RemoteControlService for a given
    /// target. If the target is not in a state that allows opening up the
    /// remote control, will wait until it is. It is the client's responsibilty
    /// to handle potential timeouts here otherwise it will wait indefinitely.
    ///
    /// Returns:
    /// * Empty struct on success.
    ///
    /// Errors:
    /// * See [TargetError] for failure states.
    OpenRemoteControl(resource struct {
        remote_control server_end:rc.RemoteControl;
    }) -> (struct {}) error TargetConnectionError;

    /// Opens a Fastboot controller for a given target.
    OpenFastboot(resource struct {
        fastboot server_end:Fastboot;
    });

    /// Reboots the target to the desired state.
    ///
    /// Returns:
    /// * Empty struct on success.
    ///
    /// Errors:
    /// * See [TargetRebootError] for failure states.
    Reboot(struct {
        state TargetRebootState;
    }) -> (struct {}) error TargetRebootError;


    /// Runs an iterator over diagnostics data. At present, this means cached log data.
    StreamActiveDiagnostics(resource struct {
        parameters DaemonDiagnosticsStreamParameters;
        iterator server_end:rc.ArchiveIterator;
    }) -> (struct {
        log_session LogSession;
    }) error DiagnosticsStreamError;
};
