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

using fuchsia.net as net;
using fuchsia.wlan.policy as wlan_policy;

/// The maximum number of HostPorts that Weave can return in a HostPortList, as
/// weave indexes HostPortLists by a uint8.
const MAX_HOST_PORTS uint32 = 256;
/// The largest supported size of a QR code encoded in string format may be.
const MAX_QR_CODE_SIZE uint32 = 256;

/// An endpoint ID used for identifying which service endpoints are of interest when
/// looking up endpoints in the Weave Service Directory.
alias ServiceEndpointId = uint64;

/// Current state of pairing/provisioning. At the point of a completely unprovisioned
/// or factory reset device, all states will be `false`. Outside of an explicit
/// ResetConfig call or factory reset, the provisioning states will only transition
/// from `false` to `true` as Weave profiles are provisioned.
type PairingState = table {
    /// Has Weave been fully provisioned? This implies that all provisioning
    /// has been completed as expected as specified in the configuration.
    1: is_weave_fully_provisioned bool;
    /// Has WiFi been provisioned? Defaults to false.
    2: is_wlan_provisioned bool;
    /// Has Thread been provisioned? Defaults to false.
    3: is_thread_provisioned bool;
    /// Has the fabric been provisioned? Defaults to false.
    4: is_fabric_provisioned bool;
    /// Has the service been provisioned? Defaults to false.
    5: is_service_provisioned bool;
};

/// ResetConfig flags.
type ResetConfigFlags = strict bits : uint16 {
    /// Reset network configuration information.
    NETWORK_CONFIG = 0x0001;
    /// Reset fabric configuration information.
    FABRIC_CONFIG = 0x0002;
    /// Reset service configuration information.
    SERVICE_CONFIG = 0x0004;
    /// Reset device operational credentials.
    OPERATIONAL_CREDENTIALS = 0x0008;
};

/// Reset all device configuration information.
const RESET_CONFIG_ALL uint16 = 0x00FF;

/// QR Code data for pairing.
type QrCode = struct {
    /// QR code data in string format, supplying this string in a QR
    /// code should be sufficient for pairing.
    data string:MAX_QR_CODE_SIZE;
};

/// Representation of a host either in the form of a hostname or IP address.
type Host = strict union {
    1: hostname net.Hostname;
    2: ip_address net.IpAddress;
};

/// A tuple of host and port to represent a connectable endpoint.
type HostPort = struct {
    host Host;
    port uint16;
};

/// Watches for changes in Weave Service Directory entries for a particular endpoint
/// ID. The endpoint ID is specified in, and this protocol retrieved from
/// [`fuchsia.weave/Stack.GetServiceDirectoryWatcher`].
protocol SvcDirectoryWatcher {
    /// Returns a vector of HostPorts for the watched endpoint ID.
    ///
    /// First call returns the current list of HostPorts or blocks until the list
    /// is available from the service. Subsequent calls will block until a new
    /// ServiceDirectory lookup is made and will return the list associated with
    /// the watched endpoint ID, which may or may not be the same as prior values.
    ///
    /// Calling WatchServiceDirectory when a previous call is still pending will
    /// cause the channel to be closed with `ZX_ERR_BAD_STATE`.
    WatchServiceDirectory() -> (struct {
        host_port_list vector<HostPort>:MAX_HOST_PORTS;
    });
};

/// Watches for changes in pairing state in Weave. Retrieved from
/// [`fuchsia.weave/Stack.GetPairingStateWatcher`].
protocol PairingStateWatcher {
    /// Returns the state of pairing.
    ///
    /// First call returns the current pairing state or blocks until the pairing
    /// state is available. Subsequent calls will block until the pairing state
    /// changes.
    ///
    /// Calling WatchPairingState when a previous call is still pending will cause
    /// the channel to be closed with `ZX_ERR_BAD_STATE`.
    WatchPairingState() -> (struct {
        state PairingState;
    });
};

/// Component acting as WLAN network configuration provider for WeaveStack need to
/// implement this.
protocol WlanNetworkConfigProvider {
    /// Returns current network configuration when new information is available.
    ///
    /// First call returns the current network configuration if available,
    /// otherwise return empty config. WeaveStack consumes network config
    /// and sends another request.
    WatchConnectedNetwork() -> (struct {
        network_config wlan_policy.NetworkConfig;
    });
};

/// Calls and services available from WeaveStack. These calls are designed to
/// wrap the Weave adaptation and provide information or capabilities to Weave
/// applications or components that are interested in information that Weave
/// exposes.
@discoverable
protocol Stack {
    /// Returns a PairingStateWatcher to watch for changes in pairing state.
    GetPairingStateWatcher(resource struct {
        watcher server_end:PairingStateWatcher;
    });
    /// Returns a SvcDirectoryWatcher to watch changes in the Weave service
    /// directory for a particular endpoint.
    GetSvcDirectoryWatcher(resource struct {
        endpoint_id ServiceEndpointId;
        watcher server_end:SvcDirectoryWatcher;
    });
    /// Returns a QR code that can be used in the pairing process.
    GetQrCode() -> (struct {
        qr_code QrCode;
    }) error ErrorCode;
    /// Reset the Weave configuration.
    ResetConfig(struct {
        flags ResetConfigFlags;
    }) -> (struct {}) error ErrorCode;
};

/// Services Provided to WeaveStack by other components.
@discoverable
protocol StackProvider {
    /// Registers a WLAN network configuration provider with WeaveStack.
    /// Only one provider can be set at a time.
    ///
    /// Attempts to set a new provider while there is an active provider
    /// will close the channel to active provider and will be replaced
    /// by the new provider.
    ///
    /// TODO(fxbug.dev/62322): This interface may be deprecated when current
    /// WLAN network configuration  can be shared amongst multiple components.
    SetWlanNetworkConfigProvider(resource struct {
        provider client_end:WlanNetworkConfigProvider;
    });
};
