// 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 <fuchsia/device/manager/c/fidl.h>
#include <fuchsia/device/manager/cpp/fidl.h>
#include <fuchsia/device/manager/llcpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/async/cpp/wait.h>
#include <lib/zx/channel.h>
#include <lib/zx/event.h>

#include <memory>
#include <variant>

#include <ddk/device.h>
#include <fbl/array.h>
#include <fbl/auto_lock.h>
#include <fbl/mutex.h>
#include <fbl/ref_counted.h>
#include <fbl/string.h>
#include <fs/vmo_file.h>

#include "async_loop_ref_counted_rpc_handler.h"
#include "composite_device.h"
#include "driver_test_reporter.h"
#include "inspect.h"
#include "metadata.h"

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

// clang-format off

// This device is never destroyed
#define DEV_CTX_IMMORTAL           0x0001

// This device requires that children are created in a
// new driver_host attached to a proxy device
#define DEV_CTX_MUST_ISOLATE       0x0002

// This device may be bound multiple times
#define DEV_CTX_MULTI_BIND         0x0004

// This device is bound and not eligible for binding
// again until unbound.  Not allowed on MULTI_BIND ctx.
#define DEV_CTX_BOUND              0x0008

// Device has been remove()'d
#define DEV_CTX_DEAD               0x0010

// This device is a fragment of a composite device and
// can be part of multiple composite devices.
#define DEV_CTX_ALLOW_MULTI_COMPOSITE    0x0020

// Device is a proxy -- its "parent" is the device it's
// a proxy to.
#define DEV_CTX_PROXY              0x0040

// 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          0x0080

// Device should not go through auto-bind process
#define DEV_CTX_SKIP_AUTOBIND      0x0100

// Signals used on the test event
#define TEST_BIND_DONE_SIGNAL ZX_USER_SIGNAL_0
#define TEST_SUSPEND_DONE_SIGNAL ZX_USER_SIGNAL_1
#define TEST_RESUME_DONE_SIGNAL ZX_USER_SIGNAL_2
#define TEST_REMOVE_DONE_SIGNAL ZX_USER_SIGNAL_3

constexpr zx::duration kDefaultTestTimeout = zx::sec(5);

// 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 llcpp::fuchsia::device::manager::Coordinator::Interface,
      public AsyncLoopRefCountedRpcHandler<Device>,
      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(::zx::channel coordinator, ::zx::channel device_controller,
                 ::fidl::VectorView<llcpp::fuchsia::device::manager::DeviceProperty> props,
                 ::fidl::StringView name, uint32_t protocol_id, ::fidl::StringView driver_path,
                 ::fidl::StringView args,
                 llcpp::fuchsia::device::manager::AddDeviceConfig device_add_config, bool has_init,
                 ::zx::vmo inspect, ::zx::channel client_remote,
                 AddDeviceCompleter::Sync& _completer) override;
  void ScheduleRemove(bool unbind_self, ScheduleRemoveCompleter::Sync& _completer) override;
  void AddCompositeDevice(::fidl::StringView name,
                          llcpp::fuchsia::device::manager::CompositeDeviceDescriptor comp_desc,
                          AddCompositeDeviceCompleter::Sync& _completer) override;
  void PublishMetadata(::fidl::StringView device_path, uint32_t key,
                       ::fidl::VectorView<uint8_t> data,
                       PublishMetadataCompleter::Sync& _completer) override;
  void MakeVisible(MakeVisibleCompleter::Sync& _completer) override;
  void BindDevice(::fidl::StringView driver_path, BindDeviceCompleter::Sync& _completer) override;
  void GetTopologicalPath(GetTopologicalPathCompleter::Sync& _completer) override;
  void LoadFirmware(::fidl::StringView fw_path, LoadFirmwareCompleter::Sync& _completer) override;
  void GetMetadata(uint32_t key, GetMetadataCompleter::Sync& _completer) override;
  void GetMetadataSize(uint32_t key, GetMetadataSizeCompleter::Sync& _completer) override;
  void AddMetadata(uint32_t key, ::fidl::VectorView<uint8_t> data,
                   AddMetadataCompleter::Sync& _completer) override;
  void ScheduleUnbindChildren(ScheduleUnbindChildrenCompleter::Sync& _completer) override;
  void RunCompatibilityTests(int64_t hook_wait_time,
                             RunCompatibilityTestsCompleter::Sync& _completer) override;
  void DirectoryWatch(uint32_t mask, uint32_t options, ::zx::channel watcher,
                      DirectoryWatchCompleter::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 IterType, 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, IterType>) {
              ++arg;
            } else if constexpr (std::is_same_v<T, Composite>) {
              ++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, IterType>) {
              return *arg;
            } else if constexpr (std::is_same_v<T, Composite>) {
              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, IterType>) {
                // 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, run through the Composite
                // state next.
                if (device_->parent_) {
                  state_ = Composite{device_->parent_->fragments().begin()};
                } else {
                  state_ = Composite{};
                }
                return true;
              } else if constexpr (std::is_same_v<T, Composite>) {
                // Check if this device is an internal fragment device
                // that bound to a composite fragment.  If it is, and
                // the composite has been constructed, the iterator
                // should yield the composite.
                if (device_->parent_) {
                  if (arg != device_->parent_->fragments().end() &&
                      arg->composite()->device() != nullptr) {
                    return false;
                  }
                }
                state_ = Done{};
                return false;
              } else if constexpr (std::is_same_v<T, Done>) {
                return false;
              }
            },
            state_);
      }
    }

    using Composite = fbl::TaggedDoublyLinkedList<CompositeDeviceFragment*,
                                                  CompositeDeviceFragment::DeviceListTag>::iterator;
    struct Done {
      bool operator==(Done) const { return true; }
    };
    std::variant<IterType, Composite, 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, bool wait_make_visible = false);
  ~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,
                            zx::channel coordinator_rpc, zx::channel device_controller_rpc,
                            bool wait_make_visible, bool want_init_task, bool skip_autobind,
                            zx::vmo inspect, zx::channel client_remote,
                            fbl::RefPtr<Device>* device);
  static zx_status_t CreateComposite(Coordinator* coordinator, fbl::RefPtr<DriverHost> driver_host,
                                     const CompositeDevice& composite, zx::channel coordinator_rpc,
                                     zx::channel device_controller_rpc,
                                     fbl::RefPtr<Device>* device);
  zx_status_t CreateProxy();

  static void HandleRpc(fbl::RefPtr<Device>&& dev, async_dispatcher_t* dispatcher,
                        async::WaitBase* wait, zx_status_t status,
                        const zx_packet_signal_t* signal);

  // 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, Device>;
  using ConstChildListIterator =
      ChildListIterator<fbl::TaggedDoublyLinkedList<Device*, ChildListTag>::const_iterator,
                        const Device>;
  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.
  zx_status_t 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.
  zx_status_t 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.
  zx_status_t 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.
  zx_status_t SendUnbind(UnbindCompletion completion);
  // Issue a CompleteRemoval request to this device.
  // When the response comes in, the given completion will be invoked.
  zx_status_t SendCompleteRemoval(RemoveCompletion completion);

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

  // Sets the properties of this device.  Returns an error if the properties
  // array contains more than one property from the BIND_TOPO_* range.
  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 zx_device_prop_t* topo_prop() const { return topo_prop_; }

  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_; }

  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;
  }
  void disassociate_from_composite() { composite_ = UnassociatedWithComposite{}; }

  void set_host(fbl::RefPtr<DriverHost> host);
  const fbl::RefPtr<DriverHost>& host() const { 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 |CompleteRemoval| 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, unbind or remove request.
  void DropInitTask() { active_init_ = nullptr; }
  void DropUnbindTask() { active_unbind_ = nullptr; }
  void DropRemoveTask() { active_remove_ = nullptr; }

  zx_status_t DriverCompatibiltyTest();

  zx::channel take_client_remote() { return std::move(client_remote_); }

  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));
  }

  State state() const { return state_; }

  void clear_wait_make_visible() { wait_make_visible_ = false; }
  bool wait_make_visible() const { return wait_make_visible_; }

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

  void InitializeInspectValues();

  enum class TestStateMachine {
    kTestNotStarted = 1,
    kTestUnbindSent,
    kTestBindSent,
    kTestBindDone,
    kTestSuspendSent,
    kTestSuspendDone,
    kTestResumeSent,
    kTestResumeDone,
    kTestDone,
  };

  TestStateMachine test_state() {
    fbl::AutoLock<fbl::Mutex> lock(&test_state_lock_);
    return test_state_;
  }

  void set_test_state(TestStateMachine new_state) {
    fbl::AutoLock<fbl::Mutex> lock(&test_state_lock_);
    test_state_ = new_state;
  }

  void clear_active_resume() { active_resume_ = nullptr; }
  void set_test_time(zx::duration& test_time) { test_time_ = test_time; }
  void set_test_reply_required(bool required) { test_reply_required_ = required; }
  zx::duration& test_time() { return test_time_; }
  const char* GetTestDriverName();
  zx::event& test_event() { return test_event_; }

  // This is public for testing purposes.
  std::unique_ptr<DriverTestReporter> test_reporter;

  zx_status_t set_test_output(zx::channel test_output, async_dispatcher_t* dispatcher) {
    test_output_ = std::move(test_output);
    test_wait_.set_object(test_output_.get());
    test_wait_.set_trigger(ZX_CHANNEL_PEER_CLOSED);
    return test_wait_.Begin(dispatcher);
  }

  const fidl::InterfacePtr<fuchsia::device::manager::DeviceController>& device_controller() const {
    return device_controller_;
  }

  const fidl::InterfaceRequest<fuchsia::device::manager::DeviceController> ConnectDeviceController(
      async_dispatcher_t* dispatcher) {
    return device_controller_.NewRequest(dispatcher);
  }

 private:
  void HandleTestOutput(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                        const zx_packet_signal_t* signal);

  // The driver sends output from run_unit_tests over this channel.
  zx::channel test_output_;

  // Async waiter that drives the consumption of test_output_. It is triggered when the channel is
  // closed by the driver, signalling the end of the tests. We don't print log messages until the
  // entire test is finished to avoid interleaving output from multiple drivers.
  async::WaitMethod<Device, &Device::HandleTestOutput> test_wait_{this};

  fidl::InterfacePtr<fuchsia::device::manager::DeviceController> device_controller_;

  zx_status_t HandleRead();
  int RunCompatibilityTests();

  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::Array<const zx_device_prop_t> props_;
  // If the device has a topological property in |props|, this points to it.
  const zx_device_prop_t* topo_prop_ = nullptr;

  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_;

  // If true, we should only make the device visible after DdkMakeVisible is called
  // (and after the init task has completed).
  bool wait_make_visible_ = false;

  // For compatibility tests.
  fbl::Mutex test_state_lock_;
  TestStateMachine test_state_ __TA_GUARDED(test_state_lock_) = TestStateMachine::kTestNotStarted;
  zx::event test_event_;
  zx::duration test_time_;
  fuchsia_device_manager_CompatibilityTestStatus test_status_;
  bool test_reply_required_ = false;

  // 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_
