// Copyright (c) 2013 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 "mist/usb_device.h"

#include <libusb.h>

#include <base/logging.h>

#include "mist/usb_config_descriptor.h"
#include "mist/usb_device_descriptor.h"

using std::string;
using std::unique_ptr;

namespace mist {

UsbDevice::UsbDevice(libusb_device* device)
    : device_(device), device_handle_(nullptr) {
  CHECK(device_);
  libusb_ref_device(device_);
}

UsbDevice::UsbDevice(libusb_device_handle* device_handle)
    : device_(nullptr), device_handle_(device_handle) {
  CHECK(device_handle_);
  device_ = libusb_get_device(device_handle_);
  CHECK(device_);
  libusb_ref_device(device_);
}

UsbDevice::~UsbDevice() {
  Close();
  libusb_unref_device(device_);
  device_ = nullptr;
}

bool UsbDevice::IsOpen() const {
  return device_handle_ != nullptr;
}

bool UsbDevice::VerifyOpen() {
  if (IsOpen())
    return true;

  error_.set_type(UsbError::kErrorDeviceNotOpen);
  return false;
}

bool UsbDevice::Open() {
  if (IsOpen()) {
    error_.Clear();
    return true;
  }

  int result = libusb_open(device_, &device_handle_);
  return error_.SetFromLibUsbError(static_cast<libusb_error>(result));
}

void UsbDevice::Close() {
  if (!IsOpen())
    return;

  libusb_close(device_handle_);
  device_handle_ = nullptr;
}

bool UsbDevice::Reset() {
  if (!VerifyOpen())
    return false;

  int result = libusb_reset_device(device_handle_);
  return error_.SetFromLibUsbError(static_cast<libusb_error>(result));
}

uint8_t UsbDevice::GetBusNumber() const {
  return libusb_get_bus_number(device_);
}

uint8_t UsbDevice::GetDeviceAddress() const {
  return libusb_get_device_address(device_);
}

UsbSpeed UsbDevice::GetDeviceSpeed() const {
  int speed = libusb_get_device_speed(device_);
  switch (speed) {
    case kUsbSpeedLow:
    case kUsbSpeedFull:
    case kUsbSpeedHigh:
    case kUsbSpeedSuper:
      return static_cast<UsbSpeed>(speed);
    default:
      return kUsbSpeedUnknown;
  }
}

bool UsbDevice::GetConfiguration(int* configuration) {
  if (!VerifyOpen())
    return false;

  int result = libusb_get_configuration(device_handle_, configuration);
  return error_.SetFromLibUsbError(static_cast<libusb_error>(result));
}

bool UsbDevice::SetConfiguration(int configuration) {
  if (!VerifyOpen())
    return false;

  int result = libusb_set_configuration(device_handle_, configuration);
  return error_.SetFromLibUsbError(static_cast<libusb_error>(result));
}

bool UsbDevice::ClaimInterface(int interface_number) {
  if (!VerifyOpen())
    return false;

  int result = libusb_claim_interface(device_handle_, interface_number);
  return error_.SetFromLibUsbError(static_cast<libusb_error>(result));
}

bool UsbDevice::ReleaseInterface(int interface_number) {
  if (!VerifyOpen())
    return false;

  int result = libusb_release_interface(device_handle_, interface_number);
  return error_.SetFromLibUsbError(static_cast<libusb_error>(result));
}

bool UsbDevice::SetInterfaceAlternateSetting(int interface_number,
                                             int alternate_setting) {
  if (!VerifyOpen())
    return false;

  int result = libusb_set_interface_alt_setting(
      device_handle_, interface_number, alternate_setting);
  return error_.SetFromLibUsbError(static_cast<libusb_error>(result));
}

bool UsbDevice::IsKernelDriverActive(int interface_number) {
  if (!VerifyOpen())
    return false;

  int result = libusb_kernel_driver_active(device_handle_, interface_number);
  if (result == 1) {
    error_.Clear();
    return true;
  }

  return error_.SetFromLibUsbError(static_cast<libusb_error>(result));
}

bool UsbDevice::AttachKernelDriver(int interface_number) {
  if (!VerifyOpen())
    return false;

  int result = libusb_attach_kernel_driver(device_handle_, interface_number);
  return error_.SetFromLibUsbError(static_cast<libusb_error>(result));
}

bool UsbDevice::DetachKernelDriver(int interface_number) {
  if (!VerifyOpen())
    return false;

  int result = libusb_detach_kernel_driver(device_handle_, interface_number);
  return error_.SetFromLibUsbError(static_cast<libusb_error>(result));
}

bool UsbDevice::ClearHalt(uint8_t endpoint) {
  if (!VerifyOpen())
    return false;

  int result = libusb_clear_halt(device_handle_, endpoint);
  return error_.SetFromLibUsbError(static_cast<libusb_error>(result));
}

UsbConfigDescriptor* UsbDevice::GetActiveConfigDescriptor() {
  libusb_config_descriptor* config_descriptor = nullptr;

  int result = libusb_get_active_config_descriptor(device_, &config_descriptor);
  if (error_.SetFromLibUsbError(static_cast<libusb_error>(result)))
    return new UsbConfigDescriptor(AsWeakPtr(), config_descriptor, true);

  return nullptr;
}

UsbConfigDescriptor* UsbDevice::GetConfigDescriptor(uint8_t index) {
  libusb_config_descriptor* config_descriptor = nullptr;

  int result = libusb_get_config_descriptor(device_, index, &config_descriptor);
  if (error_.SetFromLibUsbError(static_cast<libusb_error>(result)))
    return new UsbConfigDescriptor(AsWeakPtr(), config_descriptor, true);

  return nullptr;
}

UsbConfigDescriptor* UsbDevice::GetConfigDescriptorByValue(
    uint8_t configuration_value) {
  libusb_config_descriptor* config_descriptor = nullptr;

  int result = libusb_get_config_descriptor_by_value(
      device_, configuration_value, &config_descriptor);
  if (error_.SetFromLibUsbError(static_cast<libusb_error>(result)))
    return new UsbConfigDescriptor(AsWeakPtr(), config_descriptor, true);

  return nullptr;
}

UsbDeviceDescriptor* UsbDevice::GetDeviceDescriptor() {
  if (!device_descriptor_)
    device_descriptor_.reset(new libusb_device_descriptor());

  int result = libusb_get_device_descriptor(device_, device_descriptor_.get());
  if (error_.SetFromLibUsbError(static_cast<libusb_error>(result)))
    return new UsbDeviceDescriptor(AsWeakPtr(), device_descriptor_.get());

  return nullptr;
}

string UsbDevice::GetStringDescriptorAscii(uint8_t index) {
  if (!VerifyOpen())
    return string();

  // libusb_get_string_descriptor_ascii uses an internal buffer that can only
  // hold up to 128 ASCII characters.
  int length = 128;
  unique_ptr<uint8_t[]> data(new uint8_t[length]);
  int result = libusb_get_string_descriptor_ascii(device_handle_, index,
                                                  data.get(), length);
  if (result < 0) {
    error_.SetFromLibUsbError(static_cast<libusb_error>(result));
    return string();
  }

  error_.Clear();
  return string(reinterpret_cast<const char*>(data.get()), result);
}

}  // namespace mist
