// Copyright 2019 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_DEVICE_H_
#define SRC_DEVICES_BIN_DRIVER_MANAGER_DEVICE_H_

#include <fidl/fuchsia.device.manager/cpp/wire.h>
#include <fidl/fuchsia.driver.development/cpp/wire.h>
#include <fidl/fuchsia.io/cpp/wire.h>
#include <lib/async/cpp/task.h>
#include <lib/async/cpp/wait.h>
#include <lib/ddk/device.h>
#include <lib/zx/channel.h>
#include <lib/zx/event.h>

#include <memory>
#include <variant>

#include <fbl/array.h>
#include <fbl/auto_lock.h>
#include <fbl/mutex.h>
#include <fbl/ref_counted.h>
#include <fbl/string.h>

#include "src/devices/bin/driver_manager/composite_device.h"
#include "src/devices/bin/driver_manager/inspect.h"
#include "src/devices/bin/driver_manager/metadata.h"
#include "src/lib/storage/vfs/cpp/vmo_file.h"

namespace fio = fuchsia_io;

class Coordinator;
class DriverHost;
struct Devnode;
class InitTask;
class RemoveTask;
class SuspendTask;
class ResumeTask;
class UnbindTask;
struct UnbindTaskOpts;

// clang-format off

// This device is never destroyed
#define DEV_CTX_IMMORTAL           static_cast<uint32_t>(fuchsia_driver_development::DeviceFlags::kImmortal)

// This device requires that children are created in a
// new driver_host attached to a proxy device
#define DEV_CTX_MUST_ISOLATE           static_cast<uint32_t>(fuchsia_driver_development::DeviceFlags::kMustIsolate)

// This device may be bound multiple times
#define DEV_CTX_MULTI_BIND           static_cast<uint32_t>(fuchsia_driver_development::DeviceFlags::kMultiBind)

// This device is bound and not eligible for binding
// again until unbound.  Not allowed on MULTI_BIND ctx.
#define DEV_CTX_BOUND           static_cast<uint32_t>(fuchsia_driver_development::DeviceFlags::kBound)

// Device has been remove()'d
#define DEV_CTX_DEAD           static_cast<uint32_t>(fuchsia_driver_development::DeviceFlags::kDead)

// This device is a fragment of a composite device and
// can be part of multiple composite devices.
#define DEV_CTX_ALLOW_MULTI_COMPOSITE           static_cast<uint32_t>(fuchsia_driver_development::DeviceFlags::kAllowMultiComposite)

// Device is a proxy -- its "parent" is the device it's
// a proxy to.
#define DEV_CTX_PROXY           static_cast<uint32_t>(fuchsia_driver_development::DeviceFlags::kProxy)

// Device is not visible in devfs or bindable.
// Devices may be created in this state, but may not
// return to this state once made visible.
#define DEV_CTX_INVISIBLE           static_cast<uint32_t>(fuchsia_driver_development::DeviceFlags::kInvisible)

// Device should not go through auto-bind process
#define DEV_CTX_SKIP_AUTOBIND           static_cast<uint32_t>(fuchsia_driver_development::DeviceFlags::kSkipAutobind)

// Device is a bus device.
#define DEV_CTX_BUS_DEVICE           static_cast<uint32_t>(fuchsia_driver_development::DeviceFlags::kBusDevice)

// clang-format on

// Tags used for container membership identification
namespace internal {
struct DeviceChildListTag {};
struct DeviceDriverHostListTag {};
struct DeviceAllDevicesListTag {};
}  // namespace internal

class Device
    : public fbl::RefCounted<Device>,
      public fidl::WireServer<fuchsia_device_manager::Coordinator>,
      public fbl::ContainableBaseClasses<
          fbl::TaggedDoublyLinkedListable<Device*, internal::DeviceChildListTag>,
          fbl::TaggedDoublyLinkedListable<Device*, internal::DeviceDriverHostListTag>,
          fbl::TaggedDoublyLinkedListable<fbl::RefPtr<Device>, internal::DeviceAllDevicesListTag>> {
 public:
  using ChildListTag = internal::DeviceChildListTag;
  using DriverHostListTag = internal::DeviceDriverHostListTag;
  using AllDevicesListTag = internal::DeviceAllDevicesListTag;

  void AddDevice(AddDeviceRequestView request, AddDeviceCompleter::Sync& _completer) override;
  void ScheduleRemove(ScheduleRemoveRequestView request,
                      ScheduleRemoveCompleter::Sync& _completer) override;
  void AddCompositeDevice(AddCompositeDeviceRequestView request,
                          AddCompositeDeviceCompleter::Sync& _completer) override;
  void AddDeviceGroup(AddDeviceGroupRequestView request,
                      AddDeviceGroupCompleter::Sync& _completer) override;
  void BindDevice(BindDeviceRequestView request, BindDeviceCompleter::Sync& _completer) override;
  void GetTopologicalPath(GetTopologicalPathRequestView request,
                          GetTopologicalPathCompleter::Sync& _completer) override;
  void LoadFirmware(LoadFirmwareRequestView request,
                    LoadFirmwareCompleter::Sync& _completer) override;
  void GetMetadata(GetMetadataRequestView request, GetMetadataCompleter::Sync& _completer) override;
  void GetMetadataSize(GetMetadataSizeRequestView request,
                       GetMetadataSizeCompleter::Sync& _completer) override;
  void AddMetadata(AddMetadataRequestView request, AddMetadataCompleter::Sync& _completer) override;
  void ScheduleUnbindChildren(ScheduleUnbindChildrenRequestView request,
                              ScheduleUnbindChildrenCompleter::Sync& _completer) override;

  // This iterator provides access to a list of devices that does not provide
  // mechanisms for mutating that list.  With this, a user can get mutable
  // access to a device in the list.  This is achieved by making the linked
  // list iterator opaque. It is not safe to modify the underlying list while
  // this iterator is in use.
  template <typename ChildIterType, typename FragmentIterType, typename DeviceType>
  class ChildListIterator {
   public:
    ChildListIterator() : state_(Done{}) {}
    explicit ChildListIterator(DeviceType* device)
        : state_(device->children_.begin()), device_(device) {
      SkipInvalidStates();
    }
    ChildListIterator operator++(int) {
      auto other = *this;
      ++*this;
      return other;
    }
    bool operator==(const ChildListIterator& other) const { return state_ == other.state_; }
    bool operator!=(const ChildListIterator& other) const { return !(state_ == other.state_); }

    // The iterator implementation for the child list.  This is the source of truth
    // for what devices are children of the device.
    ChildListIterator& operator++() {
      std::visit(
          [this](auto&& arg) {
            using T = std::decay_t<decltype(arg)>;
            if constexpr (std::is_same_v<T, ChildIterType> || std::is_same_v<T, FragmentIterType>) {
              ++arg;
            } else if constexpr (std::is_same_v<T, Done>) {
              state_ = Done{};
            }
          },
          state_);
      SkipInvalidStates();
      return *this;
    }

    DeviceType& operator*() const {
      return std::visit(
          [](auto&& arg) -> DeviceType& {
            using T = std::decay_t<decltype(arg)>;
            if constexpr (std::is_same_v<T, ChildIterType>) {
              return *arg;
            } else if constexpr (std::is_same_v<T, FragmentIterType>) {
              return *(arg->composite()->device());
            } else {
              __builtin_trap();
            }
          },
          state_);
    }

   private:
    // Advance the iterator to the next valid state or reach the done state.
    // This is used to handle advancement between the different state variants.
    void SkipInvalidStates() {
      bool more = true;
      while (more) {
        more = std::visit(
            [this](auto&& arg) {
              using T = std::decay_t<decltype(arg)>;
              if constexpr (std::is_same_v<T, ChildIterType>) {
                // Check if there are any more children in the list.  If
                // there are, we're in a valid state and can stop.
                // Otherwise, advance to the next variant and check if
                // it's a valid state.
                if (arg != device_->children_.end()) {
                  return false;
                }

                // If there are no more children and this is a fragment device,
                // find children of the fragment device by looking at its parent's
                // fragment list.
                if (device_->libname() == device_->coordinator->GetFragmentDriverUrl()) {
                  if (device_->parent_) {
                    state_ = FragmentIterType{device_->parent()->fragments_.begin()};
                    return true;
                  }
                  state_ = Done{};
                  return false;
                }

                // Some composite devices are added directly as fragments without
                // a proxy fragment device. These don't appear in the children list.
                state_ = FragmentIterType{device_->fragments_.begin()};
                return true;
              } else if constexpr (std::is_same_v<T, FragmentIterType>) {
                if (device_->libname() == device_->coordinator->GetFragmentDriverUrl()) {
                  // This device is an internal fragment device.
                  if (arg == device_->parent()->fragments_.end()) {
                    state_ = Done{};
                    return false;
                  }

                  // Skip composite devices that aren't yet bound.
                  if (arg->composite()->device() == nullptr) {
                    state_ = FragmentIterType{++arg};
                    return true;
                  }

                  // Skip any fragments that aren't bound to this fragment device.
                  if (arg->fragment_device().get() != device_) {
                    state_ = FragmentIterType{++arg};
                    return true;
                  }

                  return false;
                }

                // Check for composite devices that don't have proxy fragment devices.

                if (arg == device_->fragments_.end()) {
                  state_ = Done{};
                  return false;
                }

                // Skip composite devices that aren't yet bound.
                if (arg->composite()->device() == nullptr) {
                  state_ = FragmentIterType{++arg};
                  return true;
                }

                // Skip fragments that have a fragment device.
                if (arg->fragment_device() != nullptr) {
                  state_ = FragmentIterType{++arg};
                  return true;
                }

                return false;
              } else if constexpr (std::is_same_v<T, Done>) {
                return false;
              }
            },
            state_);
      }
    }
    struct Done {
      bool operator==(Done) const { return true; }
    };
    std::variant<ChildIterType, FragmentIterType, Done> state_;
    DeviceType* device_;
  };

  // This class exists to allow consumers of the Device class to write
  //   for (auto& child : dev->children())
  // and get mutable access to the children without getting mutable access to
  // the list.
  template <typename DeviceType, typename IterType>
  class ChildListIteratorFactory {
   public:
    explicit ChildListIteratorFactory(DeviceType* device) : device_(device) {}

    IterType begin() const { return IterType(device_); }
    IterType end() const { return IterType(); }

    bool is_empty() const { return begin() == end(); }

   private:
    DeviceType* device_;
  };

  Device(Coordinator* coord, fbl::String name, fbl::String libname, fbl::String args,
         fbl::RefPtr<Device> parent, uint32_t protocol_id, zx::vmo inspect,
         zx::channel client_remote, fidl::ClientEnd<fio::Directory> outgoing_dir);
  ~Device();

  // Create a new device with the given parameters.  This sets up its
  // relationship with its parent and driver_host and adds its RPC channel to the
  // coordinator's async loop.  This does not add the device to the
  // coordinator's devices_ list, or trigger publishing
  static zx_status_t Create(
      Coordinator* coordinator, const fbl::RefPtr<Device>& parent, fbl::String name,
      fbl::String driver_path, fbl::String args, uint32_t protocol_id,
      fbl::Array<zx_device_prop_t> props, fbl::Array<StrProperty> str_props,
      fidl::ServerEnd<fuchsia_device_manager::Coordinator> coordinator_request,
      fidl::ClientEnd<fuchsia_device_manager::DeviceController> device_controller,
      bool want_init_task, bool skip_autobind, zx::vmo inspect, zx::channel client_remote,
      fidl::ClientEnd<fio::Directory> outgoing_dir, fbl::RefPtr<Device>* device);
  static zx_status_t CreateComposite(
      Coordinator* coordinator, fbl::RefPtr<DriverHost> driver_host,
      const CompositeDevice& composite,
      fidl::ServerEnd<fuchsia_device_manager::Coordinator> coordinator_request,
      fidl::ClientEnd<fuchsia_device_manager::DeviceController> device_controller,
      fbl::RefPtr<Device>* device);
  zx_status_t CreateProxy();
  zx_status_t CreateNewProxy();

  static void Bind(fbl::RefPtr<Device> dev, async_dispatcher_t*,
                   fidl::ServerEnd<fuchsia_device_manager::Coordinator>);

  // We do not want to expose the list itself for mutation, even if the
  // children are allowed to be mutated.  We manage this by making the
  // iterator opaque.
  using NonConstChildListIterator = ChildListIterator<
      fbl::TaggedDoublyLinkedList<Device*, ChildListTag>::iterator,
      fbl::TaggedDoublyLinkedList<CompositeDeviceFragment*,
                                  CompositeDeviceFragment::DeviceListTag>::iterator,
      Device>;
  using ConstChildListIterator = ChildListIterator<
      fbl::TaggedDoublyLinkedList<Device*, ChildListTag>::const_iterator,
      fbl::TaggedDoublyLinkedList<CompositeDeviceFragment*,
                                  CompositeDeviceFragment::DeviceListTag>::const_iterator,
      const Device>;

  using NonConstFragmentListIterator =
      fbl::TaggedDoublyLinkedList<CompositeDeviceFragment*,
                                  CompositeDeviceFragment::DeviceListTag>::iterator;

  using NonConstChildListIteratorFactory =
      ChildListIteratorFactory<Device, NonConstChildListIterator>;
  using ConstChildListIteratorFactory =
      ChildListIteratorFactory<const Device, ConstChildListIterator>;
  NonConstChildListIteratorFactory children() { return NonConstChildListIteratorFactory(this); }
  ConstChildListIteratorFactory children() const { return ConstChildListIteratorFactory(this); }

  // Signal that this device is ready for bind to happen.  This should happen
  // either immediately after the device is created, if it's created visible,
  // or after it becomes visible.
  zx_status_t SignalReadyForBind(zx::duration delay = zx::sec(0));

  using InitCompletion = fit::callback<void(zx_status_t)>;
  // Issue an Init request to this device.  When the response comes in, the
  // given completion will be invoked.
  void SendInit(InitCompletion completion);

  using SuspendCompletion = fit::callback<void(zx_status_t)>;
  // Issue a Suspend request to this device.  When the response comes in, the
  // given completion will be invoked.
  void SendSuspend(uint32_t flags, SuspendCompletion completion);

  using ResumeCompletion = fit::callback<void(zx_status_t)>;
  // Issue a Resume request to this device.  When the response comes in, the
  // given completion will be invoked.
  void SendResume(uint32_t target_system_state, ResumeCompletion completion);

  using UnbindCompletion = fit::callback<void(zx_status_t)>;
  using RemoveCompletion = fit::callback<void(zx_status_t)>;
  // Issue an Unbind request to this device, which will run the unbind hook.
  // When the response comes in, the given completion will be invoked.
  // If successful, returns ZX_OK and takes ownership of |completion|.
  void SendUnbind(UnbindCompletion& completion);
  // Issue a CompleteRemove request to this device.
  // When the response comes in, the given completion will be invoked.
  // If successful, returns ZX_OK and takes ownership of |completion|.
  void SendCompleteRemove(RemoveCompletion& completion);

  // Break the relationship between this device object and its parent
  void DetachFromParent();

  // Sets the properties of this device.
  zx_status_t SetProps(fbl::Array<const zx_device_prop_t> props);
  const fbl::Array<const zx_device_prop_t>& props() const { return props_; }

  const fbl::Array<const StrProperty>& str_props() const { return str_props_; }
  zx_status_t SetStrProps(fbl::Array<const StrProperty> str_props);

  const fbl::RefPtr<Device>& parent() { return parent_; }
  fbl::RefPtr<const Device> parent() const { return parent_; }

  const fbl::RefPtr<Device>& proxy() { return proxy_; }
  fbl::RefPtr<const Device> proxy() const { return proxy_; }

  const fbl::RefPtr<Device>& new_proxy() { return new_proxy_; }
  fbl::RefPtr<const Device> new_proxy() const { return new_proxy_; }

  uint32_t protocol_id() const { return protocol_id_; }

  DeviceInspect& inspect() { return *inspect_; }

  bool is_bindable() const {
    return !(flags & (DEV_CTX_BOUND | DEV_CTX_INVISIBLE)) && (state_ != Device::State::kDead);
  }

  bool should_skip_autobind() const { return flags & DEV_CTX_SKIP_AUTOBIND; }

  bool is_visible() const { return !(flags & DEV_CTX_INVISIBLE); }

  bool is_composite_bindable() const {
    if (flags & (DEV_CTX_DEAD | DEV_CTX_INVISIBLE | DEV_CTX_SKIP_AUTOBIND)) {
      return false;
    }
    if ((flags & DEV_CTX_BOUND) && !(flags & DEV_CTX_ALLOW_MULTI_COMPOSITE)) {
      return false;
    }
    return true;
  }

  void push_fragment(CompositeDeviceFragment* fragment) { fragments_.push_back(fragment); }
  bool is_fragments_empty() { return fragments_.is_empty(); }

  fbl::TaggedDoublyLinkedList<CompositeDeviceFragment*, CompositeDeviceFragment::DeviceListTag>&
  fragments() {
    return fragments_;
  }
  // If the device was created as a composite, this returns its description.
  CompositeDevice* composite() const {
    auto val = std::get_if<CompositeDevice*>(&composite_);
    return val ? *val : nullptr;
  }
  void set_composite(CompositeDevice* composite) {
    ZX_ASSERT(std::holds_alternative<UnassociatedWithComposite>(composite_));
    composite_ = composite;
  }
  bool is_composite() const { return composite() != nullptr; }
  void disassociate_from_composite() { composite_ = UnassociatedWithComposite{}; }

  void set_host(fbl::RefPtr<DriverHost> host);
  const fbl::RefPtr<DriverHost>& host() const { return host_; }
  fbl::RefPtr<DriverHost>& host() { return host_; }

  void set_local_id(uint64_t local_id) {
    local_id_ = local_id;
    inspect().set_local_id(local_id);
  }
  uint64_t local_id() const { return local_id_; }

  const fbl::DoublyLinkedList<std::unique_ptr<Metadata>>& metadata() const { return metadata_; }
  void AddMetadata(std::unique_ptr<Metadata> md) { metadata_.push_front(std::move(md)); }

  // Creates the init task for the device.
  void CreateInitTask();
  // Returns the in-progress init task if it exists, nullptr otherwise.
  fbl::RefPtr<InitTask> GetActiveInit() { return active_init_; }

  // Run the completion for the outstanding init, if any.
  zx_status_t CompleteInit(zx_status_t status);

  // Returns the in-progress suspend task if it exists, nullptr otherwise.
  fbl::RefPtr<SuspendTask> GetActiveSuspend() { return active_suspend_; }
  // Creates a new suspend task if necessary and returns a reference to it.
  // If one is already in-progress, a reference to it is returned instead
  fbl::RefPtr<SuspendTask> RequestSuspendTask(uint32_t suspend_flags);

  fbl::RefPtr<ResumeTask> GetActiveResume() { return active_resume_; }
  void SetActiveResume(fbl::RefPtr<ResumeTask> resume_task) { active_resume_ = resume_task; }

  // Request Resume task
  fbl::RefPtr<ResumeTask> RequestResumeTask(uint32_t system_resume_state);

  // Run the completion for the outstanding suspend, if any.  This method is
  // only exposed currently because RemoveDevice is on Coordinator instead of
  // Device.
  void CompleteSuspend(zx_status_t status);

  // Run the completion for the outstanding resume, if any.
  void CompleteResume(zx_status_t status);

  // Creates the unbind and remove tasks for the device if they do not already exist.
  // |opts| is used to configure the unbind task.
  void CreateUnbindRemoveTasks(UnbindTaskOpts opts);

  // Returns the in-progress unbind task if it exists, nullptr otherwise.
  // Unbind tasks are used to facilitate |Unbind| requests.
  fbl::RefPtr<UnbindTask> GetActiveUnbind() { return active_unbind_; }
  // Returns the in-progress remove task if it exists, nullptr otherwise.
  // Remove tasks are used to facilitate |CompleteRemove| requests.
  fbl::RefPtr<RemoveTask> GetActiveRemove() { return active_remove_; }

  // Run the completion for the outstanding unbind, if any.
  zx_status_t CompleteUnbind(zx_status_t status = ZX_OK);
  // Run the completion for the outstanding remove, if any.
  zx_status_t CompleteRemove(zx_status_t status = ZX_OK);

  // Drops the reference to the task.
  // This should be called if the device will not send an init, suspend, unbind or remove request.
  void DropInitTask() { active_init_ = nullptr; }
  void DropSuspendTask() { active_suspend_ = nullptr; }
  void DropUnbindTask() { active_unbind_ = nullptr; }
  void DropRemoveTask() { active_remove_ = nullptr; }

  zx::channel take_client_remote() { return std::move(client_remote_); }
  bool has_outgoing_directory() { return outgoing_dir_.is_valid(); }
  fidl::ClientEnd<fio::Directory> take_outgoing_dir() { return std::move(outgoing_dir_); }

  const fbl::String& name() const { return name_; }
  const fbl::String& libname() const { return libname_; }
  const fbl::String& args() const { return args_; }

  Coordinator* coordinator;
  uint32_t flags = 0;

  // The backoff between each driver retry. This grows exponentially.
  zx::duration backoff = zx::msec(250);
  // The number of retries left for the driver.
  uint32_t retries = 4;
  Devnode* self = nullptr;
  Devnode* link = nullptr;

  Devnode* devnode() { return self; }

  const fbl::String& link_name() const { return link_name_; }
  void set_link_name(fbl::String link_name) { link_name_ = std::move(link_name); }

  fbl::RefPtr<fs::VmoFile>& inspect_file() { return inspect_file_; }

  // TODO(teisenbe): We probably want more states.
#define STATE_VALUES(macro)                                                                        \
  macro(kActive)                                                                                   \
      macro(kInitializing) /* The driver_host is in the process of running the device init hook.*/ \
      macro(kSuspending)   /* The driver_host is in the process of suspending the device.*/        \
      macro(kSuspended)                                                                            \
          macro(kResuming) /* The driver_host is in the process of resuming the device.*/          \
      macro(kResumed) /* Resume is complete. Will be marked active, after all children resume.*/   \
      macro(                                                                                       \
          kUnbinding) /* The driver_host is in the process of unbinding and removing the device.*/ \
      macro(kDead)    /* The device has been remove()'d*/

#define MAKE_ENUM_VALUE(state) state,
  enum class State { STATE_VALUES(MAKE_ENUM_VALUE) };
#undef ENUM_VALUE
#define MAKE_SWITCH_STATEMENT(state) \
  case State::state:                 \
    return #state;
  static std::string StateToString(State state) {
    switch (state) { STATE_VALUES(MAKE_SWITCH_STATEMENT) }
  }
#undef MAKE_SWITCH_STATEMENT
#undef STATE_VALUES

  void set_state(Device::State state) {
    state_ = state;
    inspect().set_state(StateToString(state));

    if (state == Device::State::kDead) {
      if (std::optional binding = std::exchange(coordinator_binding_, std::nullopt);
          binding.has_value()) {
        binding.value().Unbind();
      }
    }
  }

  State state() const { return state_; }

  void inc_num_removal_attempts() { num_removal_attempts_++; }
  size_t num_removal_attempts() const { return num_removal_attempts_; }

  void InitializeInspectValues();

  void clear_active_resume() { active_resume_ = nullptr; }

  const fidl::WireSharedClient<fuchsia_device_manager::DeviceController>& device_controller()
      const {
    return device_controller_;
  }

  fidl::WireSharedClient<fuchsia_device_manager::DeviceController>& device_controller() {
    return device_controller_;
  }

  const std::optional<fidl::ServerBindingRef<fuchsia_device_manager::Coordinator>>&
  coordinator_binding() const {
    return coordinator_binding_;
  }

  const fidl::ServerEnd<fuchsia_device_manager::DeviceController> ConnectDeviceController(
      async_dispatcher_t* dispatcher) {
    auto endpoints = fidl::CreateEndpoints<fuchsia_device_manager::DeviceController>();
    device_controller_.Bind(std::move(endpoints->client), dispatcher);
    return std::move(endpoints->server);
  }

  bool DriverLivesInSystemStorage() const;

  // Returns true if this device already has a driver bound.
  bool IsAlreadyBound() const;

 private:
  fidl::WireSharedClient<fuchsia_device_manager::DeviceController> device_controller_;
  std::optional<fidl::ServerBindingRef<fuchsia_device_manager::Coordinator>> coordinator_binding_;

  const fbl::String name_;
  const fbl::String libname_;
  const fbl::String args_;

  fbl::RefPtr<Device> parent_;
  const uint32_t protocol_id_;

  fbl::RefPtr<Device> proxy_;
  fbl::RefPtr<Device> new_proxy_;

  fbl::Array<const zx_device_prop_t> props_;

  fbl::Array<const StrProperty> str_props_;

  async::TaskClosure publish_task_;

  // List of all child devices of this device, except for composite devices.
  // Composite devices are excluded because their multiple-parent nature
  // precludes using the same intrusive nodes as single-parent devices.
  fbl::TaggedDoublyLinkedList<Device*, ChildListTag> children_;

  // Metadata entries associated to this device.
  fbl::DoublyLinkedList<std::unique_ptr<Metadata>> metadata_;

  // list of all fragments that this device bound to.
  fbl::TaggedDoublyLinkedList<CompositeDeviceFragment*, CompositeDeviceFragment::DeviceListTag>
      fragments_;

  // - If this device is part of a composite device, this is inhabited by
  //   CompositeDeviceFragment* and it points to the fragment that matched it.
  //   Note that this is only set on the device that matched the fragment, not
  //   the "fragment device" added by the fragment driver.
  // - If this device is a composite device, this is inhabited by
  //   CompositeDevice* and it points to the composite that describes it.
  // - Otherwise, it is inhabited by UnassociatedWithComposite
  struct UnassociatedWithComposite {};
  std::variant<UnassociatedWithComposite, CompositeDevice*> composite_;

  fbl::RefPtr<DriverHost> host_;
  // The id of this device from the perspective of the driver_host.  This can be
  // used to communicate with the driver_host about this device.
  uint64_t local_id_ = 0;

  // The current state of the device
  State state_ = State::kActive;

  // If an init is in-progress, this task represents it.
  fbl::RefPtr<InitTask> active_init_;
  // If an init is in-progress, this completion will be invoked when it is
  // completed.  It will likely mark |active_init_| as completed and clear it.
  InitCompletion init_completion_;

  // If a suspend is in-progress, this task represents it.
  fbl::RefPtr<SuspendTask> active_suspend_;
  // If a suspend is in-progress, this completion will be invoked when it is
  // completed.  It will likely mark |active_suspend_| as completed and clear
  // it.
  SuspendCompletion suspend_completion_;

  // If a resume is in-progress, this task represents it.
  fbl::RefPtr<ResumeTask> active_resume_;
  // If a Resume is in-progress, this completion will be invoked when it is
  // completed.
  ResumeCompletion resume_completion_;

  // If an unbind is in-progress, this task represents it.
  fbl::RefPtr<UnbindTask> active_unbind_;
  // If an unbind is in-progress, this completion will be invoked when it is
  // completed. It will likely mark |active_unbind_| as completed and clear
  // it.
  UnbindCompletion unbind_completion_;

  // If a remove is in-progress, this task represents it.
  fbl::RefPtr<RemoveTask> active_remove_;
  // If a remove is in-progress, this completion will be invoked when it is
  // completed. It will likely mark |active_remove_| as completed and clear
  // it.
  RemoveCompletion remove_completion_;

  // Name of the inspect vmo file as it appears in diagnostics class directory
  fbl::String link_name_;

  fbl::RefPtr<fs::VmoFile> inspect_file_;

  // For attaching as an open connection to the proxy device,
  // or once the device becomes visible.
  zx::channel client_remote_;

  // Provides incoming directory for the driver which binds to this device.
  fidl::ClientEnd<fio::Directory> outgoing_dir_;

  // This lets us check for unexpected removals and is for testing use only.
  size_t num_removal_attempts_ = 0;

  std::optional<DeviceInspect> inspect_;
};

#endif  // SRC_DEVICES_BIN_DRIVER_MANAGER_DEVICE_H_
