// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "permission_broker/libusb_wrapper.h"

#include <string>
#include <utility>

#include <base/logging.h>
#include <base/time/time.h>

namespace {

constexpr base::TimeDelta kUsbControlTimeout = base::TimeDelta::FromSeconds(5);

const int kLibusbUnrefDevices = 1;

}  // namespace

namespace permission_broker {

UsbDevice::UsbDevice(libusb_device* device)
    : device_(device, libusb_unref_device) {
  // Increase the ref count to gain ownership of the libusb device object.
  libusb_ref_device(device_.get());

  // Try to obtain information regarding the device VID/PID from the device
  // itself.
  // NB: in the repositories we only depend on versions of libusb which are
  //     newer than 1.0.16. This means that we can ignore the return value
  //     as this API always suceeds in such a case.
  libusb_device_descriptor descriptor;
  libusb_get_device_descriptor(device_.get(), &descriptor);
  info_.vid = descriptor.idVendor;
  info_.pid = descriptor.idProduct;
  info_.device_class = descriptor.bDeviceClass;
}

UsbDevice::~UsbDevice() = default;

UsbDeviceInfo UsbDevice::GetInfo() const {
  return info_;
}

std::unique_ptr<UsbDeviceInterface> UsbDevice::GetParent() const {
  libusb_device* parent_device = libusb_get_parent(device_.get());
  if (parent_device == nullptr) {
    LOG(ERROR) << "Unable to find the device parent for '" << info_ << "'";
    return nullptr;
  }
  auto parent = std::unique_ptr<UsbDeviceInterface>(
      new UsbDevice(parent_device));

  UsbDeviceInfo parent_info = parent->GetInfo();
  if (parent_info.device_class != LIBUSB_CLASS_HUB) {
    LOG(ERROR) << "The parent device found for this USB device is not a hub ("
               << parent_info << ")";
    return nullptr;
  }

  return parent;
}

uint8_t UsbDevice::GetPort() const {
  return libusb_get_port_number(device_.get());
}

bool UsbDevice::SetPowerState(bool enabled, uint16_t port) const {
  if (info_.device_class != LIBUSB_CLASS_HUB) {
    LOG(ERROR) << "Unable to set power on a port if the device is not a hub "
               << "(device '" << info_ << "')";
    return false;
  }

  libusb_device_handle* handle;
  int result = libusb_open(device_.get(), &handle);
  if (result != LIBUSB_SUCCESS) {
    LOG(ERROR) << "Unable to open the USB device. (error: "
               << libusb_error_name(result) << ")";
    return false;
  }

  uint8_t request =
      enabled ? LIBUSB_REQUEST_SET_FEATURE : LIBUSB_REQUEST_CLEAR_FEATURE;
  result = libusb_control_transfer(
      handle, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER, request,
      USB_PORT_FEAT_POWER, port, nullptr, 0,
      kUsbControlTimeout.InMilliseconds());
  libusb_close(handle);

  if (result < 0) {
    std::string status = enabled ? "on" : "off";
    LOG(WARNING) << "Unable to power " << status << " device '" << info_
                 << "' (error: " << libusb_error_name(result) << ")";
    return false;
  }

  return true;
}

UsbDeviceManager::UsbDeviceManager() {
  libusb_context* ctx;
  int status = libusb_init(&ctx);
  if (status != LIBUSB_SUCCESS) {
    LOG(ERROR) << "Unable to initialize the libusb context. (error: "
               << libusb_error_name(status) << ")";
    return;
  }
  context_.reset(ctx);
}

UsbDeviceManager::~UsbDeviceManager() = default;

std::vector<std::unique_ptr<UsbDeviceInterface>>
UsbDeviceManager::GetDevicesByVidPid(uint16_t vid, uint16_t pid) {
  libusb_device** device_list;
  std::vector<std::unique_ptr<UsbDeviceInterface>> devices;

  int num_of_devices = libusb_get_device_list(context_.get(), &device_list);
  if (num_of_devices < 0) {
    LOG(ERROR) << "Unable to access the libusb device list. (error: "
               << libusb_error_name(num_of_devices) << ")";
    return devices;
  }

  for (int i = 0; i < num_of_devices; ++i) {
    auto device = std::make_unique<UsbDevice>(device_list[i]);
    UsbDeviceInfo info = device->GetInfo();

    if (info.vid == vid && info.pid == pid) {
      devices.push_back(std::move(device));
    }
  }

  // Free the list of devices previously retrieved.
  libusb_free_device_list(device_list, kLibusbUnrefDevices);
  return devices;
}

}  // namespace permission_broker
