// Copyright 2021 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.development;

using fuchsia.driver.framework;
using fuchsia.url;
using zx;

const BINDING_RESULT_MAX uint8 = 10;

const HASH_LENGTH uint8 = 64;

/// Interface for the driver development manager.
/// This interface should only be used for development and disabled in release builds.
@discoverable(server="platform")
open protocol Manager {
    /// Returns a list of all drivers that are known to the system.
    /// If a |driver_filter| is provided, the returned list will be filtered to
    /// only include drivers specified in the filter.
    ///
    /// |iterator| is closed with following epitaphs on error:
    /// ZX_ERR_NOT_FOUND indicates that there is no driver matching the given path for at least
    /// one driver in |driver_filter|.
    /// ZX_ERR_BUFFER_TOO_SMALL indicates that the driver's bind program is longer than the
    /// maximum number of instructions (BIND_PROGRAM_INSTRUCTIONS_MAX).
    flexible GetDriverInfo(resource struct {
        driver_filter vector<string:MAX>:MAX;
        iterator server_end:DriverInfoIterator;
    });

    /// Returns a list of all composite node specs that are known to the system.
    /// If a |name_filter| is provided, the returned list will only include 1 spec,
    /// the one with that exact name.
    ///
    /// |iterator| is closed with following epitaphs on error:
    /// ZX_ERR_NOT_FOUND indicates that there are no specs or if a |name_filter| is provided,
    /// that there are no specs with that name.
    flexible GetCompositeNodeSpecs(resource struct {
        name_filter string:<MAX, optional>;
        iterator server_end:CompositeNodeSpecIterator;
    });

    /// Returns the list of nodes that are running on the system.
    ///
    /// If a |node_filter| is provided, the returned list will be filtered to
    /// only include nodes specified in the filter. If |exact_match| is true,
    /// then the filter must exactly match a node's topological path;
    /// otherwise, it performs a substring match. The list will be empty if no
    /// nodes match the filter.
    ///
    /// |iterator| is closed with following epitaphs on error:
    /// ZX_ERR_BAD_PATH indicates that the given path is not valid.
    /// ZX_ERR_BUFFER_TOO_SMALL indicates either that the given path is too long,
    /// or that the node has more than the maximum number of properties (PROPERTIES_MAX).
    flexible GetNodeInfo(resource struct {
        node_filter vector<string:MAX>:MAX;
        iterator server_end:NodeInfoIterator;
        exact_match bool;
    });

    /// Returns the list of composites in the system. This includes composites
    /// that are not yet assembled and added into the node topology.
    flexible GetCompositeInfo(resource struct {
        iterator server_end:CompositeInfoIterator;
    });

    /// Restarts all driver hosts containing the driver specified by the `driver_url`,
    /// and returns the number of driver hosts that were restarted.
    /// The |rematch_flags| will be used to decide for which restarting nodes the existing driver
    /// should be bound vs. for which ones the matching process should be performed again.
    flexible RestartDriverHosts(struct {
        driver_url fuchsia.url.Url;
        rematch_flags RestartRematchFlags;
    }) -> (struct {
        count uint32;
    }) error zx.Status;

    /// Disables the driver with the given driver component url.
    /// Disabled drivers will not be considered for matching to nodes.
    /// If a |package_hash| is provided, only that specific version of the driver
    /// package will be disabled. Otherwise this applies to all existing versions
    /// of a driver with the given url.
    /// Returns an error ZX_ERR_NOT_FOUND if no drivers were affected.
    flexible DisableDriver(struct {
        driver_url fuchsia.url.Url;
        package_hash string:<HASH_LENGTH, optional>;
    }) -> () error zx.Status;

    /// Enables the driver with the given driver component url.
    /// This is only meant to revert a |DisableDriver| action.
    /// Returns an error ZX_ERR_NOT_FOUND if no drivers were affected.
    flexible EnableDriver(struct {
        driver_url fuchsia.url.Url;
        package_hash string:<HASH_LENGTH, optional>;
    }) -> () error zx.Status;

    /// Attempts to bind all unbound nodes in the topology.
    /// Returns new successful binds.
    flexible BindAllUnboundNodes() -> (struct {
        /// List of new bindings that happened as a result of this.
        binding_result vector<NodeBindingInfo>:BINDING_RESULT_MAX;
    }) error zx.Status;

    /// Adds test node under the root node.
    flexible AddTestNode(struct {
        args TestNodeAddArgs;
    }) -> () error fuchsia.driver.framework.NodeError;

    /// Removes the test node. The node is removed asynchronously and is
    /// not guaranteed to be removed by the time this returns.
    flexible RemoveTestNode(struct {
        name string:NODE_MONIKER_MAX;
    }) -> () error zx.Status;

    /// Waits for bootup to complete.
    @available(added=21)
    strict WaitForBootup() -> ();
};

/// Interface for watching when bootup is complete, in which there are no more bind and driver start
/// activity.
@available(added=20, removed=21)
@discoverable
open protocol BootupWatcher {
    // Waits for bootup to complete.
    strict WaitForBootup() -> ();
};
