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

#ifndef SRC_DEVICES_BIN_DRIVER_MANAGER_BIND_DRIVER_MANAGER_H_
#define SRC_DEVICES_BIN_DRIVER_MANAGER_BIND_DRIVER_MANAGER_H_

#include <lib/ddk/device.h>

#include <memory>

#include "src/devices/bin/driver_manager/coordinator.h"
#include "src/devices/bin/driver_manager/driver_loader.h"
#include "src/devices/bin/driver_manager/v1/init_task.h"
#include "src/devices/bin/driver_manager/v1/resume_task.h"
#include "src/devices/bin/driver_manager/v1/suspend_task.h"
#include "src/devices/bin/driver_manager/v1/unbind_task.h"

class CompositeDevice;

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

using CompositeDeviceMap = std::unordered_map<std::string, std::unique_ptr<CompositeDevice>>;

class BindDriverManager {
 public:
  BindDriverManager(const BindDriverManager&) = delete;
  BindDriverManager& operator=(const BindDriverManager&) = delete;
  BindDriverManager(BindDriverManager&&) = delete;
  BindDriverManager& operator=(BindDriverManager&&) = delete;

  BindDriverManager(Coordinator* coordinator, AttemptBindFunc attempt_bind);
  ~BindDriverManager();

  // Returns ZX_OK if |device| and |driver| are a match for binding.
  zx_status_t MatchDevice(const fbl::RefPtr<Device>& dev, const Driver* driver,
                          bool autobind) const;

  zx_status_t BindDriverToDevice(const MatchedDriver& driver, 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, std::string_view drvlibname,
                         bool new_device);

  // 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 MatchAndBind(const fbl::RefPtr<Device>& dev, const Driver* driver, bool autobind);

  // Given a device, return all of the Drivers whose bind programs match with the device.
  // The returned vector is organized by priority, so if only one driver is being bound it
  // should be the first in the vector.
  // If |drvlibname| is not empty then the device will only be checked against the driver
  // with that specific name.
  zx::status<std::vector<MatchedDriver>> GetMatchingDrivers(const fbl::RefPtr<Device>& dev,
                                                            std::string_view drvlibname);

  // Binds all the devices to the drivers in the Driver Index.
  void BindAllDevicesDriverIndex(const DriverLoader::MatchDeviceConfig& config);

  zx_status_t AddDeviceGroup(std::string_view topological_path, std::string_view group_name,
                             fuchsia_device_manager::wire::DeviceGroupDescriptor group_desc);

  // Public for testing only.
  void set_attempt_bind(AttemptBindFunc attempt_bind) { attempt_bind_ = std::move(attempt_bind); }

  // Only exposed for testing.
  const std::unordered_map<std::string, std::unique_ptr<CompositeDevice>>& device_groups() const {
    return device_groups_;
  }

 private:
  // Find and return matching drivers for |dev| in the Driver Index.
  zx::status<std::vector<MatchedDriver>> MatchDeviceWithDriverIndex(
      const fbl::RefPtr<Device>& dev, const DriverLoader::MatchDeviceConfig& config) const;

  // Find matching drivers for |dev| through the Driver Index and then bind them.
  zx_status_t MatchAndBindWithDriverIndex(const fbl::RefPtr<Device>& dev,
                                          const DriverLoader::MatchDeviceConfig& config);

  zx_status_t MatchAndBindDeviceGroup(const fbl::RefPtr<Device>& dev,
                                      std::string_view topological_path);

  // Binds the matched fragment in |driver| to |dev|. If a CompositeDevice for |driver| doesn't
  // exists in |driver_index_composite_devices_|, this function creates and adds it.
  zx_status_t BindDriverToFragment(const MatchedCompositeDriverInfo& driver,
                                   const fbl::RefPtr<Device>& dev);

  zx_status_t BindDriverToDeviceGroup(const MatchedDeviceGroupInfo& device_group,
                                      const fbl::RefPtr<Device>& dev);

  // Owner. Must outlive BindDriverManager.
  Coordinator* coordinator_;

  // Callback function. Used to attempt binding a driver to a device.
  // TODO(fxb/90932): Remove this callback.
  AttemptBindFunc attempt_bind_;

  // All the composite devices received from the DriverIndex.
  // This maps driver URLs to the CompositeDevice object.
  CompositeDeviceMap driver_index_composite_devices_;

  // All the composite devices for device groups received from the DriverIndex.
  // This maps topological paths to the CompositeDevice object.
  CompositeDeviceMap device_groups_;
};

#endif  // SRC_DEVICES_BIN_DRIVER_MANAGER_BIND_DRIVER_MANAGER_H_
