// Copyright 2023 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.
// Draft Prototype of Protocols to be used by Power Broker.
// None of these protocols should be considered fully baked at this time
// and should be expected to change in the future as we gain information
// through this prototype testbed about coverage and usability.
@available(added=HEAD)
library fuchsia.power.broker;

using zx;

/// Used to describe the power level of an element.
/// Could extend this further to support additional types of power
/// levels, such as ACPI.
alias PowerLevel = uint8;

/// BinaryPowerLevel is a well-known set of PowerLevels with only two
/// states: OFF and ON.
type BinaryPowerLevel = strict enum : PowerLevel {
    OFF = 0;
    ON = 1;
};

/// See the #fulfillment-policy-definition of the Power Topology RFC:
/// https://fuchsia-review.googlesource.com/c/fuchsia/+/1004754 for a description of dependency
/// types. Note, ACTIVE and PASSIVE are not concepts in the RFC and readers should interpret
/// assertive as ACTIVE and opportunistic as PASSIVE.
// TODO(b/341766303): make dependency types and comments consistent with Power Topology RFC once it
// has been accepted.
type DependencyType = strict enum {
    ACTIVE = 1;
    PASSIVE = 2;
};

const MAX_ELEMENT_NAME_LEN uint16 = 1024;

/// A token that represents the right to add a dependency upon another
/// element. Should first be registered with Power Broker via
/// ElementControl.RegisterDependencyToken of the required element.
alias DependencyToken = zx.Handle:EVENT;

/// Power dependency from an already specified element's PowerLevel to another.
/// The dependent Element should already be known from context.
type LevelDependency = resource struct {
    /// Must match the expected type of the DependencyToken, i.e. ACTIVE must be used if the token
    /// is specified to be an active dependency token and PASSIVE must be used if the token is
    /// specified to be a passive dependency token.
    // TODO(b/341766303): make this comment consistent with Power Topology RFC once it has been
    // accepted.
    dependency_type DependencyType;
    dependent_level PowerLevel;
    /// Must supply a token registered via the RegisterDependencyToken call of
    /// the required element's ElementControl protocol.
    requires_token DependencyToken;
    requires_level PowerLevel;
};

/// This is the primary initial protocol used by Power Element Owners to
/// communicate with Power Broker. Power Element Owners should add the
/// elements they own to the Power Topology through AddElement. All further
/// interactions with Power Broker are done through channels opened by the
/// AddElement call, which are scoped to the added element.
@discoverable
open protocol Topology {
    /// Called by a Power Element owner to register a new Power Element and
    /// open control channels for that element.
    flexible AddElement(ElementSchema) -> (resource struct {
        /// ElementControl channel for this element.
        /// When this channel is dropped, the element will be removed from the
        /// topology. All channels associated with this element will be
        /// closed and all tokens registered to this element will be
        /// unregistered.
        element_control_channel client_end:ElementControl;
    }) error AddElementError;
};

/// Passed to Topology.AddElement.
type ElementSchema = resource table {
    /// Human-readable name for logging and debug purposes.
    1: element_name string:MAX_ELEMENT_NAME_LEN;
    /// The initial current power level of the element.
    2: initial_current_level PowerLevel;
    /// All power levels that are valid for this element. Any level not
    /// specified here will be treated as invalid.
    3: valid_levels vector<PowerLevel>:MAX_VALID_POWER_LEVELS;
    /// List of dependencies for this element's power levels.
    /// Note: dependencies UPON this element's levels cannot be added here.
    4: dependencies vector<LevelDependency>:MAX_DEPENDENCIES_IN_ADD_ELEMENT;
    /// List of active dependency tokens to register for this element.
    /// These tokens will allow other element owners to create active
    /// dependencies upon this element by passing them as the
    /// requires_token of a LevelDependency.
    5: active_dependency_tokens_to_register vector<DependencyToken>:MAX_TOKENS_IN_ADD_ELEMENT;
    /// List of passive dependency tokens to register for this element.
    /// These tokens will allow other element owners to create passive
    /// dependencies upon this element by passing them as the
    /// requires_token of a LevelDependency.
    6: passive_dependency_tokens_to_register vector<DependencyToken>:MAX_TOKENS_IN_ADD_ELEMENT;
    /// Channels on which Power Broker will send required power levels and
    /// receive current level updates.
    7: level_control_channels LevelControlChannels;
    /// Optional. If passed, this will be treated as a consumer element and
    /// Leases for this element can be requested via this channel.
    8: lessor_channel server_end:Lessor;
};

type LevelControlChannels = resource struct {
    /// Channel on which Power Broker will receive current level updates
    /// for this element.
    current server_end:CurrentLevel;
    /// Channel on which Power Broker will send required power levels
    /// for this element.
    required server_end:RequiredLevel;
};

// Limitations on vector length for the sake of bounding request size.
const MAX_DEPENDENCIES_IN_ADD_ELEMENT uint16 = 128;
const MAX_TOKENS_IN_ADD_ELEMENT uint16 = 128;
const MAX_VALID_POWER_LEVELS uint16 = 256;

type AddElementError = flexible enum {
    INTERNAL = 1;
    INVALID = 2;
    NOT_AUTHORIZED = 3;
};

/// Provides element-scoped access to an element previously added via
/// Topology.AddElement.
open protocol ElementControl {
    /// Register a new Status channel on which Power Broker will send
    /// read-only updates of the element's current power level. This method
    /// is intended to allow element owners to give read-only access to the
    /// element's current power level to clients by opening and transferring
    /// this channel.
    flexible OpenStatusChannel(resource struct {
        status_channel server_end:Status;
    });

    /// Register a token which will permit the bearer to add either an
    /// active or passive dependency upon this element, depending on the
    /// dependency_type specified.
    flexible RegisterDependencyToken(resource struct {
        token DependencyToken;
        dependency_type DependencyType;
    }) -> () error RegisterDependencyTokenError;

    /// Unregister a token previously registered via RegisterDependencyToken.
    flexible UnregisterDependencyToken(resource struct {
        token DependencyToken;
    }) -> () error UnregisterDependencyTokenError;
};

type ModifyDependencyError = flexible enum {
    ALREADY_EXISTS = 1;
    INVALID = 2;
    NOT_AUTHORIZED = 3;
    NOT_FOUND = 4;
};

type RegisterDependencyTokenError = flexible enum {
    ALREADY_IN_USE = 1;
    INTERNAL = 2;
};

type UnregisterDependencyTokenError = flexible enum {
    NOT_AUTHORIZED = 1;
    NOT_FOUND = 2;
};

/// Element Permissions
type Permissions = strict bits : uint32 {
    MODIFY_ACTIVE_DEPENDENT = 0b00000001;
    MODIFY_PASSIVE_DEPENDENT = 0b0000010;
    MODIFY_DEPENDENCY = 0b00000100;
};

/// CurrentLevel and RequiredLevel must both be used by all managed
/// Power Elements as part of the power level handshake with Power Broker:
/// * The element operator calls RequiredLevel.Watch to receive the next
///   required level from Power Broker.
/// * The operator makes the changes necessary to transition to the new
///   required level.
/// * The operator calls CurrentLevel.Update to inform Power Broker
///   that it has completed the transition to the new level.
/// Established via Topology.AddElement.
open protocol CurrentLevel {
    /// Sent by the element on initial startup and whenever there is a change
    /// in power level.
    flexible Update(resource struct {
        current_level PowerLevel;
    }) -> () error CurrentLevelError;
};

type CurrentLevelError = flexible enum {
    NOT_AUTHORIZED = 1;
};

/// Part of the power level handshake with Power Broker used for receiving
/// required levels from Power Broker. See above note on CurrentLevel.
/// Established via Topology.AddElement.
open protocol RequiredLevel {
    /// Returns the required power level for this element. The first call on
    /// this channel will return immediately. Subsequent calls will block until
    /// the required power level has changed.
    flexible Watch() -> (resource struct {
        required_level PowerLevel;
    }) error RequiredLevelError;
};

type RequiredLevelError = flexible enum {
    INTERNAL = 1;
    NOT_AUTHORIZED = 2;
    UNKNOWN = 3;
};

// Unique ID provided by Power Broker (currently a UUID but subject to change).
alias LeaseId = string:64;

/// Provides element-scoped access to request leases to raise the levels of an
/// element previously added via Topology.AddElement.
open protocol Lessor {
    /// Request made to indicate client intends to raise the given element
    /// to the given power level and wants to have its direct and transitive
    /// power dependencies satisfied. When `LeaseControl.WatchStatus` reports
    /// `LeaseStatus::SATISFIED` this does not indicate the `PowerElement` is at
    /// the leased `PowerLevel`. Instead this indicates that the dependencies of
    /// the leased `PowerLevel` are at level required by the `PowerLevel`.
    flexible Lease(resource struct {
        /// Power level of this element to be raised to.
        level PowerLevel;
    }) -> (resource struct {
        /// Channel for actions to be taken on the lease.
        /// When this channel is closed, the lease will be dropped.
        lease_control client_end:LeaseControl;
    }) error LeaseError;
};

type LeaseError = flexible enum {
    INTERNAL = 1;
    NOT_AUTHORIZED = 2;
};

type LeaseStatus = flexible enum {
    UNKNOWN = 0;
    /// The dependencies of the leased `PowerLevel` are not at their required
    /// levels.
    PENDING = 1;
    /// The `PowerElement` is **not** necessarily at the `PowerLevel` leased,
    /// but the `PowerElement`s requried by the leased `PowerLevel`' are at
    /// their required `PowerLevel`s.
    SATISFIED = 2;
};

/// Provides lease-scoped access to actions that can be taken on a lease
/// previously acquired via Lessor.Lease. Closing this control channel drops
/// the lease.
/// TODO(https://fxbug.dev/339474151): Switch from a protocol to an eventpair.
open protocol LeaseControl {
    /// Get the current status of the lease.
    /// If last_status is UNKNOWN, the call will return immediately
    /// with the current status. Otherwise, the call will block
    /// until the current status differs from last_status.
    // TODO(b/333947976): Remove this method once unused.
    @available(deprecated=HEAD, note="Use CurrentLevel/RequiredLevel interface instead.")
    flexible WatchStatus(struct {
        last_status LeaseStatus;
    }) -> (struct {
        status LeaseStatus;
    });
};

/// Provides read-only access to the current PowerLevel of an element and the
/// ability to watch changes to an element's power level. A new channel to
/// this protocol can be obtained by calling OpenStatus on the element's
/// ElementControl channel (and passed to other clients who need access
/// to the element's current power level).
open protocol Status {
    /// Returns the current power level for this element. The first call on
    /// this channel will return immediately. Subsequent calls will block until
    /// the current power level has changed.
    flexible WatchPowerLevel() -> (resource struct {
        current_level PowerLevel;
    }) error StatusError;
};

type StatusError = flexible enum {
    UNKNOWN = 1;
};

/// PowerLevel name lengths are limited to reduce Inspect space usage
const MAX_LEVEL_NAME_LEN uint16 = 16;

/// Status client endpoint and a plaintext name for a specific Power Element. Names are
/// expected to be unique between elements and persistent across reboots of the same build,
/// but consistency is not guaranteed between different builds.
type ElementStatusEndpoint = resource table {
    1: identifier string:MAX_ELEMENT_NAME_LEN;
    2: status client_end:Status;
};

/// Mapping of a plaintext name to a PowerLevel. Names are expected to be unique between
/// elements and persistent across reboots of the same build, but consistency is not
/// guaranteed between different builds.
type PowerLevelName = table {
    1: level PowerLevel;
    2: name string:MAX_LEVEL_NAME_LEN;
};

/// Mapping of a vector of [`fuchsia.power.broker/PowerLevelName`] to a Power Element via
/// its plaintext name. Names are expected to be unique between elements and persistent
/// across reboots of the same build, but consistency is not guaranteed between different builds.
type ElementPowerLevelNames = table {
    1: identifier string:MAX_ELEMENT_NAME_LEN;
    2: levels vector<PowerLevelName>:MAX_VALID_POWER_LEVELS;
};

/// Provides an interface to retrieve information about PowerElements managed by a component.
@discoverable
open protocol ElementInfoProvider {
    /// Returns mappings of PowerLevels to plaintext names for each element managed
    /// by a component. Returns an error if no mappings can be returned.
    flexible GetElementPowerLevelNames() -> (resource struct {
        level_names vector<ElementPowerLevelNames>:MAX;
    }) error ElementInfoProviderError;

    /// Returns available Status client endpoints and stable identifiers for each
    /// element managed by a component. Returns an error if no endpoints can be
    /// returned (i.e. no elements were able to implement the Status channel).
    flexible GetStatusEndpoints() -> (resource struct {
        endpoints vector<ElementStatusEndpoint>:MAX;
    }) error ElementInfoProviderError;
};

type ElementInfoProviderError = flexible enum {
    UNKNOWN = 0;
    FAILED = 1;
};

service ElementInfoProviderService {
    status_provider client_end:ElementInfoProvider;
};
