// 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`].
closed 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`.
    strict WatchServiceDirectory() -> (struct {
        host_port_list vector<HostPort>:MAX_HOST_PORTS;
    });
};

/// Watches for changes in pairing state in Weave. Retrieved from
/// [`fuchsia.weave/Stack.GetPairingStateWatcher`].
closed 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`.
    strict WatchPairingState() -> (struct {
        state PairingState;
    });
};

/// Component acting as WLAN network configuration provider for WeaveStack need to
/// implement this.
closed 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.
    strict 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
closed protocol Stack {
    /// Returns a PairingStateWatcher to watch for changes in pairing state.
    strict GetPairingStateWatcher(resource struct {
        watcher server_end:PairingStateWatcher;
    });
    /// Returns a SvcDirectoryWatcher to watch changes in the Weave service
    /// directory for a particular endpoint.
    strict GetSvcDirectoryWatcher(resource struct {
        endpoint_id ServiceEndpointId;
        watcher server_end:SvcDirectoryWatcher;
    });
    /// Returns a QR code that can be used in the pairing process.
    strict GetQrCode() -> (struct {
        qr_code QrCode;
    }) error ErrorCode;
    /// Reset the Weave configuration.
    strict ResetConfig(struct {
        flags ResetConfigFlags;
    }) -> () error ErrorCode;
};

/// Services Provided to WeaveStack by other components.
@discoverable
closed 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(https://fxbug.dev/42140705): This interface may be deprecated when current
    /// WLAN network configuration  can be shared amongst multiple components.
    strict SetWlanNetworkConfigProvider(resource struct {
        provider client_end:WlanNetworkConfigProvider;
    });
};
