// 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.driver.framework;

using fuchsia.device.fs;
using fuchsia.component;
using fuchsia.component.decl;
using fuchsia.io;

using zx;

alias NodePropertyKeyString = string:256;
alias NodePropertyKeyUint = uint32;
alias NodePropertyValueUint = uint32;
alias NodePropertyValueString = string:256;
alias NodePropertyValueBool = bool;
alias NodePropertyValueEnum = string:256;

const MAX_OFFER_COUNT uint32 = fuchsia.component.MAX_DYNAMIC_OFFER_COUNT;
const MAX_SYMBOL_COUNT uint8 = 64;
const MAX_PROPERTY_COUNT uint8 = 64;

const MAX_NODE_NAME_LENGTH uint8 = 128;
const MAX_SYMBOL_NAME_LENGTH uint8 = 128;

alias NodePropertyVector = vector<NodeProperty>:MAX_PROPERTY_COUNT;
alias NodeName = string:MAX_NODE_NAME_LENGTH;

/// Definition of a symbol provided by a driver for a node. A symbol is local to
/// a driver host.
type NodeSymbol = table {
    /// Name of the symbol.
    1: name string:MAX_SYMBOL_NAME_LENGTH;

    /// Virtual address of the symbol, within a driver host's process.
    2: address uint64;
};

type NodePropertyKey = strict union {
    1: int_value NodePropertyKeyUint;
    2: string_value NodePropertyKeyString;
};

type NodePropertyValue = flexible union {
    1: int_value NodePropertyValueUint;
    2: string_value NodePropertyValueString;
    3: bool_value NodePropertyValueBool;
    4: enum_value NodePropertyValueEnum;
};

/// Definition of a property for a node. A property is commonly used to match a
/// node to a driver for driver binding.
type NodeProperty = struct {
    /// Key for the property.
    key NodePropertyKey;

    /// Value for the property.
    value NodePropertyValue;
};

// Arguments for adding a node to the devfs filesystem.
type DevfsAddArgs = resource table {
    /// This is the connector to be installed in devfs.
    /// `Connect()` will be called when a client connects to this node in the filesystem.
    /// Optional: If this is not provided then an empty node will appear in devfs.
    1: connector client_end:fuchsia.device.fs.Connector;

    /// This is the class name for installing this node in devfs.
    /// The node will be placed within /dev/class/{class_name}.
    /// If `class_name` does not exist under /dev/class/ it will be created.
    /// Optional: If this is not provided then the node will only be added via topological path.
    2: class_name string:fuchsia.io.MAX_NAME_LENGTH;

    /// This is a vmo of inspect data that will be installed in devfs.
    /// Optional: If this is not provided then the devfs's inspect data will be empty.
    3: inspect zx.Handle:VMO;
};

/// Arguments for adding a node.
type NodeAddArgs = resource table {
    /// Name of the node.
    1: name NodeName;

    /// Capabilities to offer to the driver that is bound to this node.
    /// The driver must ensure these capabilities are added to its outgoing directory
    /// before adding the child node.
    2: offers vector<fuchsia.component.decl.Offer>:MAX_OFFER_COUNT;

    /// Functions to provide to the driver that is bound to this node.
    3: symbols vector<NodeSymbol>:MAX_SYMBOL_COUNT;

    /// Properties of the node.
    4: properties NodePropertyVector;

    /// The arguments for how this node should be added to devfs.
    5: devfs_args DevfsAddArgs;
};

/// Protocol through which a parent node controls one of its children.
protocol NodeController {
    /// Removes the node and all of its children.
    Remove();

    /// Request that the framework attempts to bind a driver to this node.
    /// This is an *additional* request for binding as the framework attempts to bind a node once
    /// when the node is created.
    /// * error `ZX_ERR_ALREADY_BOUND` if the node is already bound and `force_rebind` is false.
    /// * error `ZX_ERR_ALREADY_EXISTS` if the node has an outstanding |RequestBind| call which has
    /// not completed.
    RequestBind(table {
        /// If this is true, then the node unbinds from its matched driver before it attempts to
        /// bind through the normal bind process.
        1: force_rebind bool;
        /// If this is set, then only drivers matching this URL suffix will be considered in
        /// binding.
        /// E.g: "gpt.cm", "meta/gpt.cm", "fuchsia-boot:///#meta/gpt.cm".
        2: driver_url_suffix string:MAX;
    }) -> () error zx.Status;


    /// Event that is triggered when the associated `Node` is bound to a driver.
    -> OnBind();
};

/// Error codes for the Node protocol.
type NodeError = strict enum {
    // An internal error occurred.
    INTERNAL = 1;
    // The Node was removed from the topology.
    NODE_REMOVED = 2;
    // The Node's name is missing.
    NAME_MISSING = 3;
    /// The Node's name is invalid. Specifically, it must not contain a period
    /// in its name.
    NAME_INVALID = 4;
    /// A sibling Node exists with the same name.
    NAME_ALREADY_EXISTS = 5;
    /// An offer for this Node is missing a source name.
    OFFER_SOURCE_NAME_MISSING = 6;
    /// An offer for this Node should not have a source or target.
    OFFER_REF_EXISTS = 7;
    /// A symbol for this Node is missing a name.
    SYMBOL_NAME_MISSING = 8;
    /// A symbol for this Node is missing an address.
    SYMBOL_ADDRESS_MISSING = 9;
    /// There is another symbol for this Node with the same name.
    SYMBOL_ALREADY_EXISTS = 10;
};

/// Protocol through which a driver manages a node that it is bound to.
protocol Node {
    /// Adds a child node to this node.
    ///
    /// If `node` is present, this driver takes responsibility for binding to
    /// the newly created child. Otherwise, the driver framework will locate an
    /// appropriate driver to bind the child to.
    AddChild(resource struct {
        args NodeAddArgs;
        controller server_end:NodeController;
        node server_end:<Node, optional>;
    }) -> () error NodeError;
};
