// Copyright 2022 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.

#ifndef SRC_DEVICES_BIN_DRIVER_MANAGER_COMPOSITE_NODE_SPEC_COMPOSITE_NODE_SPEC_H_
#define SRC_DEVICES_BIN_DRIVER_MANAGER_COMPOSITE_NODE_SPEC_COMPOSITE_NODE_SPEC_H_

#include <fidl/fuchsia.driver.development/cpp/wire.h>
#include <fidl/fuchsia.driver.index/cpp/fidl.h>

struct DeviceV1Wrapper;

namespace driver_manager {
class Node;

using DeviceOrNode =
    std::variant<std::weak_ptr<DeviceV1Wrapper>, std::weak_ptr<driver_manager::Node>>;

using RemoveCompositeNodeCallback = fit::callback<void(zx::result<>)>;

struct CompositeNodeSpecCreateInfo {
  std::string name;
  std::vector<fuchsia_driver_framework::ParentSpec> parents;
};

// This partially abstract class represents a composite node spec and is responsible for managing
// its state and composite node. The CompositeNodeSpec class will manage the state of its bound
// nodes while its subclasses manage the composite node under the spec. There should be a subclass
// for DFv1 and DFv2.
class CompositeNodeSpec {
 public:
  explicit CompositeNodeSpec(CompositeNodeSpecCreateInfo create_info);

  virtual ~CompositeNodeSpec() = default;

  // Called when CompositeNodeManager receives a MatchedNodeRepresentation.
  // Returns ZX_ERR_ALREADY_BOUND if it's already bound. See BindParentImpl() for return type
  // details.
  zx::result<std::optional<DeviceOrNode>> BindParent(
      fuchsia_driver_framework::wire::CompositeParent composite_parent,
      const DeviceOrNode& device_or_node);

  virtual fuchsia_driver_development::wire::CompositeNodeInfo GetCompositeInfo(
      fidl::AnyArena& arena) const = 0;

  // Remove the underlying composite node and unmatch all of its parents. Called for
  // rebind.
  void Remove(RemoveCompositeNodeCallback callback);

  const std::vector<fuchsia_driver_framework::ParentSpec>& parent_specs() const {
    return parent_specs_;
  }

  // Exposed for testing.
  const std::vector<std::optional<DeviceOrNode>>& parent_nodes() const { return parent_nodes_; }

  const std::string& name() const { return name_; }

 protected:
  // Subclass implementation for binding the DeviceOrNode to its composite. If the composite is not
  // yet created, the implementation is expected to create one with |info|. In DFv1, it returns
  // std::nullopt. In DFv2, if the composite is complete, it returns a pointer to the new node.
  // Otherwise, it returns std::nullopt. The lifetime of this node object is managed by
  // the parent nodes.
  virtual zx::result<std::optional<DeviceOrNode>> BindParentImpl(
      fuchsia_driver_framework::wire::CompositeParent composite_parent,
      const DeviceOrNode& device_or_node) = 0;

  // Subclass implementation for Remove(). Subclasses are expected to remove the underlying
  // composite node and unmatch all of the parents from it.
  virtual void RemoveImpl(RemoveCompositeNodeCallback callback) = 0;

  size_t size() const { return parent_nodes_.size(); }

 private:
  std::string name_;
  std::vector<std::optional<DeviceOrNode>> parent_nodes_;
  std::vector<fuchsia_driver_framework::ParentSpec> parent_specs_;
};

}  // namespace driver_manager

#endif  // SRC_DEVICES_BIN_DRIVER_MANAGER_COMPOSITE_NODE_SPEC_COMPOSITE_NODE_SPEC_H_
