// Copyright 2017 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_COORDINATOR_H_
#define SRC_DEVICES_BIN_DRIVER_MANAGER_COORDINATOR_H_

#include <fuchsia/boot/llcpp/fidl.h>
#include <fuchsia/fshost/llcpp/fidl.h>
#include <fuchsia/power/manager/llcpp/fidl.h>
#include <lib/async/cpp/wait.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/svc/outgoing.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <lib/zx/channel.h>
#include <lib/zx/event.h>
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <lib/zx/status.h>
#include <lib/zx/vmo.h>

#include <memory>
#include <utility>

#include <ddk/binding.h>
#include <ddk/device.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/string.h>
#include <fbl/vector.h>

#include "composite_device.h"
#include "devfs.h"
#include "device.h"
#include "driver.h"
#include "driver_host.h"
#include "fbl/auto_lock.h"
#include "fuchsia/device/manager/llcpp/fidl.h"
#include "fuchsia/hardware/power/statecontrol/llcpp/fidl.h"
#include "init_task.h"
#include "inspect.h"
#include "metadata.h"
#include "resume_task.h"
#include "suspend_task.h"
#include "system_state_manager.h"
#include "unbind_task.h"
#include "vmo_writer.h"

namespace power_fidl = llcpp::fuchsia::hardware::power;
using power_fidl::statecontrol::SystemPowerState;
namespace device_manager_fidl = llcpp::fuchsia::device::manager;
namespace power_manager_fidl = llcpp::fuchsia::power::manager;

class DriverHostLoaderService;
class FsProvider;
class SystemStateManager;

constexpr zx::duration kDefaultResumeTimeout = zx::sec(30);
constexpr zx::duration kDefaultSuspendTimeout = zx::sec(30);

class SuspendContext {
 public:
  enum class Flags : uint32_t {
    kRunning = 0u,
    kSuspend = 1u,
  };

  SuspendContext() = default;

  SuspendContext(Flags flags, uint32_t sflags) : flags_(flags), sflags_(sflags) {}

  ~SuspendContext() {}

  SuspendContext(SuspendContext&&) = default;
  SuspendContext& operator=(SuspendContext&&) = default;

  void set_task(fbl::RefPtr<SuspendTask> task) { task_ = std::move(task); }

  const SuspendTask* task() const { return task_.get(); }

  Flags flags() const { return flags_; }
  void set_flags(Flags flags) { flags_ = flags; }
  uint32_t sflags() const { return sflags_; }
  async::TaskClosure* watchdog_task() const { return suspend_watchdog_task_.get(); }
  void set_suspend_watchdog_task(std::unique_ptr<async::TaskClosure> watchdog_task) {
    suspend_watchdog_task_ = std::move(watchdog_task);
  }

 private:
  fbl::RefPtr<SuspendTask> task_;
  std::unique_ptr<async::TaskClosure> suspend_watchdog_task_;

  Flags flags_ = Flags::kRunning;

  // suspend flags
  uint32_t sflags_ = 0u;
};

// Tracks the global resume state that is currently in progress.
class ResumeContext {
 public:
  enum class Flags : uint32_t {
    kResume = 0u,
    kSuspended = 1u,
  };
  ResumeContext() = default;

  ResumeContext(Flags flags, SystemPowerState resume_state)
      : target_state_(resume_state), flags_(flags) {}

  ~ResumeContext() {}

  ResumeContext(ResumeContext&&) = default;
  ResumeContext& operator=(ResumeContext&&) = default;

  Flags flags() const { return flags_; }
  void set_flags(Flags flags) { flags_ = flags; }
  void push_pending_task(fbl::RefPtr<ResumeTask> task) {
    pending_resume_tasks_.push_back(std::move(task));
  }
  void push_completed_task(fbl::RefPtr<ResumeTask> task) {
    completed_resume_tasks_.push_back(std::move(task));
  }

  bool pending_tasks_is_empty() { return pending_resume_tasks_.is_empty(); }
  bool completed_tasks_is_empty() { return completed_resume_tasks_.is_empty(); }

  std::optional<fbl::RefPtr<ResumeTask>> take_pending_task(Device& dev) {
    for (size_t i = 0; i < pending_resume_tasks_.size(); i++) {
      if (&pending_resume_tasks_[i]->device() == &dev) {
        auto task = pending_resume_tasks_.erase(i);
        return std::move(task);
      }
    }
    return {};
  }

  void reset_completed_tasks() { completed_resume_tasks_.reset(); }

  SystemPowerState target_state() const { return target_state_; }

 private:
  fbl::Vector<fbl::RefPtr<ResumeTask>> pending_resume_tasks_;
  fbl::Vector<fbl::RefPtr<ResumeTask>> completed_resume_tasks_;
  SystemPowerState target_state_;
  Flags flags_ = Flags::kSuspended;
};

using ResumeCallback = std::function<void(zx_status_t)>;
using SuspendCallback = fit::function<void(zx_status_t)>;

// Values parsed out of argv.  All paths described below are absolute paths.
struct DevmgrArgs {
  // Load drivers from these directories.  If this is empty, the default will
  // be used.
  fbl::Vector<std::string> driver_search_paths;
  // Load the drivers with these paths.  The specified drivers do not need to
  // be in directories in |driver_search_paths|.
  fbl::Vector<const char*> load_drivers;
  // Use this driver as the sys_device driver.  If nullptr, the default will
  // be used.
  std::string sys_device_driver;
  // Select whether to launch a new svchost process, or to use the /svc provided through the
  // namespace when launching subprocesses (only used in integration tests).
  bool start_svchost = true;
  // Disables the block watcher if set to true. This can be used for testing purposes,
  // where it is not necessary to have the block watcher running.
  bool disable_block_watcher = false;
  // Disables the netsvc if set to true. This can be used for testing purposes,
  // where it is not necessary to have the netsvc running.
  bool disable_netsvc = false;
  // Connect the stdout and stderr file descriptors for this program to a
  // debuglog handle acquired with fuchsia.boot.WriteOnlyLog.
  bool log_to_debuglog = false;
  // Path prefix for binaries/drivers/libraries etc.
  std::string path_prefix = "/boot/";
  // Use the default loader rather than the one provided by fshost.
  bool use_default_loader = false;
  bool no_exit_after_suspend = false;
};

struct CoordinatorConfig {
  // Initial root resource from the kernel.
  zx::resource root_resource;
  // Job for all driver_hosts.
  zx::job driver_host_job;
  // Event that is signaled by the kernel in OOM situation.
  zx::event oom_event;
  // Client for the Arguments service.
  llcpp::fuchsia::boot::Arguments::SyncClient* boot_args;
  // If true, netsvc is disabled and will not start.
  bool disable_netsvc = false;
  // Whether we require /system.
  bool require_system = false;
  // Whether we require ASan drivers.
  bool asan_drivers = false;
  // Whether to reboot the device when suspend does not finish on time.
  bool suspend_fallback = false;
  // Whether to output logs to debuglog.
  bool log_to_debuglog = false;
  // Whether to enable verbose logging.
  bool verbose = false;
  // Timeout for system wide suspend
  zx::duration suspend_timeout = kDefaultSuspendTimeout;
  // Timeout for system wide resume
  zx::duration resume_timeout = kDefaultResumeTimeout;
  // System will be transitioned to this system power state during
  // component shutdown.
  power_fidl::statecontrol::SystemPowerState default_shutdown_system_state =
      power_fidl::statecontrol::SystemPowerState::REBOOT;
  // Something to clone a handle from the environment to pass to a Devhost.
  FsProvider* fs_provider = nullptr;
  // The path prefix to find binaries, drivers, etc. Typically this is "/boot/", but in test
  // environments this might be different.
  std::string path_prefix = "/boot/";
};

struct SuspendCallbackInfo : public fbl::RefCounted<SuspendCallbackInfo> {
  SuspendCallbackInfo(SuspendCallback callback) : callback(std::move(callback)) {}
  SuspendCallback callback;
};

class Coordinator : public device_manager_fidl::BindDebugger::Interface {
 public:
  Coordinator(const Coordinator&) = delete;
  Coordinator& operator=(const Coordinator&) = delete;
  Coordinator(Coordinator&&) = delete;
  Coordinator& operator=(Coordinator&&) = delete;

  Coordinator(CoordinatorConfig config, async_dispatcher_t* dispatcher);
  ~Coordinator();

  zx_status_t InitOutgoingServices(const fbl::RefPtr<fs::PseudoDir>& svc_dir);
  zx_status_t InitCoreDevices(std::string_view sys_device_driver);
  zx::status<> InitInspect();
  bool InSuspend() const;
  bool InResume() const;

  zx_status_t ScanSystemDrivers();
  void BindDrivers();
  void UseFallbackDrivers();
  void DriverAdded(Driver* drv, const char* version);
  void DriverAddedInit(Driver* drv, const char* version);
  zx_status_t LibnameToVmo(const fbl::String& libname, zx::vmo* out_vmo) const;
  const Driver* LibnameToDriver(const fbl::StringPiece& libname) const;

  // Function that is invoked to request a driver try to bind to a device
  using AttemptBindFunc =
      fit::function<zx_status_t(const Driver* drv, const fbl::RefPtr<Device>& dev)>;

  // Attempts to bind the given driver to the given device.  Returns ZX_OK on
  // success, ZX_ERR_ALREADY_BOUND if there is a driver bound to the device
  // and the device is not allowed to be bound multiple times, ZX_ERR_NEXT if
  // the driver is not capable of binding to the device, and a different error
  // if the driver was capable of binding but failed to bind.
  zx_status_t BindDriverToDevice(const fbl::RefPtr<Device>& dev, const Driver* drv, bool autobind) {
    return BindDriverToDevice(dev, drv, autobind,
                              fit::bind_member(this, &Coordinator::AttemptBind));
  }

  // The same as above, but the given function is called to perform the
  // bind attempt.
  zx_status_t BindDriverToDevice(const fbl::RefPtr<Device>& dev, const Driver* drv, bool autobind,
                                 const AttemptBindFunc& attempt_bind);

  // Used to implement fuchsia::device::manager::Coordinator.
  // TODO(fxbug.dev/43370): remove |always_init| once init tasks can be enabled for all devices.
  zx_status_t AddDevice(const fbl::RefPtr<Device>& parent, zx::channel device_controller,
                        zx::channel coordinator,
                        const llcpp::fuchsia::device::manager::DeviceProperty* props_data,
                        size_t props_count, fbl::StringPiece name, uint32_t protocol_id,
                        fbl::StringPiece driver_path, fbl::StringPiece args, bool invisible,
                        bool skip_autobind, bool has_init, bool always_init, zx::vmo inspect,
                        zx::channel client_remote, fbl::RefPtr<Device>* new_device);
  // Begin scheduling for removal of the device and unbinding of its children.
  void ScheduleRemove(const fbl::RefPtr<Device>& dev);
  // This is for scheduling the initial unbind task as a result of a driver_host's |ScheduleRemove|
  // request.
  // If |do_unbind| is true, unbinding is also requested for |dev|.
  void ScheduleDriverHostRequestedRemove(const fbl::RefPtr<Device>& dev, bool do_unbind = false);
  void ScheduleDriverHostRequestedUnbindChildren(const fbl::RefPtr<Device>& parent);
  zx_status_t RemoveDevice(const fbl::RefPtr<Device>& dev, bool forced);
  zx_status_t MakeVisible(const fbl::RefPtr<Device>& dev);
  // Try binding a driver to the device. Returns ZX_ERR_ALREADY_BOUND if there
  // is a driver bound to the device and the device is not allowed to be bound multiple times.
  zx_status_t BindDevice(const fbl::RefPtr<Device>& dev, fbl::StringPiece drvlibname,
                         bool new_device);
  zx_status_t GetTopologicalPath(const fbl::RefPtr<const Device>& dev, char* out, size_t max) const;
  zx_status_t LoadFirmware(const fbl::RefPtr<Device>& dev, const char* path, zx::vmo* vmo,
                           size_t* size);

  zx_status_t GetMetadata(const fbl::RefPtr<Device>& dev, uint32_t type, void* buffer,
                          size_t buflen, size_t* size);
  zx_status_t GetMetadataSize(const fbl::RefPtr<Device>& dev, uint32_t type, size_t* size) {
    return GetMetadata(dev, type, nullptr, 0, size);
  }
  zx_status_t AddMetadata(const fbl::RefPtr<Device>& dev, uint32_t type, const void* data,
                          uint32_t length);
  zx_status_t PublishMetadata(const fbl::RefPtr<Device>& dev, const char* path, uint32_t type,
                              const void* data, uint32_t length);
  zx_status_t AddCompositeDevice(
      const fbl::RefPtr<Device>& dev, fbl::StringPiece name,
      llcpp::fuchsia::device::manager::CompositeDeviceDescriptor comp_desc);

  void DmMexec(zx::vmo kernel, zx::vmo bootdata);

  void HandleNewDevice(const fbl::RefPtr<Device>& dev);
  zx_status_t PrepareProxy(const fbl::RefPtr<Device>& dev,
                           fbl::RefPtr<DriverHost> target_driver_host);

  void DumpState(VmoWriter* vmo) const;

  async_dispatcher_t* dispatcher() const { return dispatcher_; }
  const zx::resource& root_resource() const { return config_.root_resource; }
  llcpp::fuchsia::boot::Arguments::SyncClient* boot_args() const { return config_.boot_args; }
  bool disable_netsvc() const { return config_.disable_netsvc; }
  bool require_system() const { return config_.require_system; }
  bool suspend_fallback() const { return config_.suspend_fallback; }
  power_fidl::statecontrol::SystemPowerState shutdown_system_state() const {
    return shutdown_system_state_;
  }
  power_fidl::statecontrol::SystemPowerState default_shutdown_system_state() const {
    return config_.default_shutdown_system_state;
  }
  void set_shutdown_system_state(power_fidl::statecontrol::SystemPowerState state) {
    shutdown_system_state_ = state;
  }

  void set_running(bool running) { running_ = running; }
  bool system_available() const { return system_available_; }
  void set_system_available(bool system_available) { system_available_ = system_available; }
  void set_power_manager_registered(bool registered) { power_manager_registered_ = registered; }
  bool power_manager_registered() { return power_manager_registered_; }
  bool system_loaded() const { return system_loaded_; }

  void set_loader_service_connector(LoaderServiceConnector loader_service_connector) {
    loader_service_connector_ = std::move(loader_service_connector);
  }

  void set_system_state_manager(std::unique_ptr<SystemStateManager> system_state_mgr) {
    system_state_manager_ = std::move(system_state_mgr);
  }

  fbl::DoublyLinkedList<std::unique_ptr<Driver>>& drivers() { return drivers_; }
  const fbl::DoublyLinkedList<std::unique_ptr<Driver>>& drivers() const { return drivers_; }
  fbl::TaggedDoublyLinkedList<fbl::RefPtr<Device>, Device::AllDevicesListTag>& devices() {
    return devices_;
  }
  const fbl::TaggedDoublyLinkedList<fbl::RefPtr<Device>, Device::AllDevicesListTag>& devices()
      const {
    return devices_;
  }

  void AppendPublishedMetadata(std::unique_ptr<Metadata> metadata) {
    published_metadata_.push_back(std::move(metadata));
  }

  const fbl::RefPtr<Device>& root_device() { return root_device_; }
  const fbl::RefPtr<Device>& misc_device() { return misc_device_; }
  const fbl::RefPtr<Device>& sys_device() { return sys_device_; }
  const fbl::RefPtr<Device>& test_device() { return test_device_; }

  void Suspend(uint32_t flags);
  void Suspend(SuspendContext ctx, fit::function<void(zx_status_t)> callback);

  void Resume(
      SystemPowerState target_state, ResumeCallback callback = [](zx_status_t) {});

  SuspendContext& suspend_context() { return suspend_context_; }
  const SuspendContext& suspend_context() const { return suspend_context_; }

  ResumeContext& resume_context() { return resume_context_; }
  const ResumeContext& resume_context() const { return resume_context_; }

  zx_status_t BindFidlServiceProxy(zx::channel listen_on);

  const Driver* fragment_driver() const { return fragment_driver_; }

  InspectManager& inspect_manager() { return inspect_manager_; }

  // This method is public only for the test suite.
  zx_status_t BindDriver(Driver* drv, const AttemptBindFunc& attempt_bind);

  uint32_t GetSuspendFlagsFromSystemPowerState(power_fidl::statecontrol::SystemPowerState state);

  // These methods are used by the DriverHost class to register in the coordinator's bookkeeping
  void RegisterDriverHost(DriverHost* dh) { driver_hosts_.push_back(dh); }
  void UnregisterDriverHost(DriverHost* dh) { driver_hosts_.erase(*dh); }

  // Returns path to driver that should be bound to fragments of composite devices.
  std::string GetFragmentDriverPath() const;

  zx_status_t RegisterWithPowerManager(zx::channel devfs_handle);
  zx_status_t RegisterWithPowerManager(zx::channel power_manager_client,
                                       zx::channel system_state_transition_client,
                                       zx::channel devfs_handle);

 protected:
  std::unique_ptr<llcpp::fuchsia::fshost::Admin::SyncClient> fshost_admin_client_;

 private:
  CoordinatorConfig config_;
  async_dispatcher_t* const dispatcher_;
  bool running_ = false;
  bool launched_first_driver_host_ = false;
  bool system_available_ = false;
  bool system_loaded_ = false;
  bool power_manager_registered_ = false;
  LoaderServiceConnector loader_service_connector_;
  fidl::Client<power_manager_fidl::DriverManagerRegistration> power_manager_client_;

  // All Drivers
  fbl::DoublyLinkedList<std::unique_ptr<Driver>> drivers_;

  // Drivers to try last
  fbl::DoublyLinkedList<std::unique_ptr<Driver>> fallback_drivers_;

  // List of drivers loaded from /system by system_driver_loader()
  fbl::DoublyLinkedList<std::unique_ptr<Driver>> system_drivers_;

  // All DriverHosts
  fbl::DoublyLinkedList<DriverHost*> driver_hosts_;

  // All Devices (excluding static immortal devices)
  fbl::TaggedDoublyLinkedList<fbl::RefPtr<Device>, Device::AllDevicesListTag> devices_;

  // All composite devices
  fbl::DoublyLinkedList<std::unique_ptr<CompositeDevice>> composite_devices_;

  fbl::RefPtr<Device> root_device_;
  fbl::RefPtr<Device> misc_device_;
  fbl::RefPtr<Device> sys_device_;
  fbl::RefPtr<Device> test_device_;

  SuspendContext suspend_context_ = {};
  ResumeContext resume_context_;

  InspectManager inspect_manager_;
  std::unique_ptr<SystemStateManager> system_state_manager_;
  power_fidl::statecontrol::SystemPowerState shutdown_system_state_;

  // Bind debugger interface
  void GetBindProgram(::fidl::StringView driver_path,
                      GetBindProgramCompleter::Sync& completer) override;
  void GetDeviceProperties(::fidl::StringView name,
                           GetDevicePropertiesCompleter::Sync& completer) override;

  void OnOOMEvent(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                  const zx_packet_signal_t* signal);
  async::WaitMethod<Coordinator, &Coordinator::OnOOMEvent> wait_on_oom_event_{this};

  fbl::DoublyLinkedList<std::unique_ptr<Metadata>> published_metadata_;

  // Once the special fragment driver is loaded, this will refer to it.  This
  // driver is used for binding against fragments of composite devices
  const Driver* fragment_driver_ = nullptr;

  void DumpDevice(VmoWriter* vmo, const Device* dev, size_t indent) const;
  void DumpDeviceProps(VmoWriter* vmo, const Device* dev) const;
  void DumpGlobalDeviceProps(VmoWriter* vmo) const;
  void DumpDrivers(VmoWriter* vmo) const;

  void BuildSuspendList();
  void Resume(ResumeContext ctx, std::function<void(zx_status_t)> callback);

  std::unique_ptr<Driver> ValidateDriver(std::unique_ptr<Driver> drv);

  zx_status_t NewDriverHost(const char* name, fbl::RefPtr<DriverHost>* out);

  zx_status_t BindDriver(Driver* drv) {
    return BindDriver(drv, fit::bind_member(this, &Coordinator::AttemptBind));
  }
  zx_status_t AttemptBind(const Driver* drv, const fbl::RefPtr<Device>& dev);
  void BindSystemDrivers();
  void DriverAddedSys(Driver* drv, const char* version);

  zx_status_t GetMetadataRecurse(const fbl::RefPtr<Device>& dev, uint32_t type, void* buffer,
                                 size_t buflen, size_t* size);

  // Shut down all filesystems (and fshost itself) by calling
  // fuchsia.fshost.Admin.Shutdown(). Note that this is called from multiple
  // different locations; during suspension, and in a low-memory situation.
  // Currently, both of these calls happen on the same dispatcher thread, but
  // consider thread safety when refactoring.
  void ShutdownFilesystems();
};

bool driver_is_bindable(const Driver* drv, uint32_t protocol_id,
                        const fbl::Array<const zx_device_prop_t>& props, bool autobind);

zx_status_t fidl_DirectoryWatch(void* ctx, uint32_t mask, uint32_t options, zx_handle_t raw_watcher,
                                fidl_txn_t* txn);

#endif  // SRC_DEVICES_BIN_DRIVER_MANAGER_COORDINATOR_H_
