// 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_interface_descriptor.h"

#include <libusb.h>

#include <memory>

#include <base/logging.h>
#include <base/strings/stringprintf.h>

#include "mist/usb_device.h"
#include "mist/usb_endpoint_descriptor.h"

using base::StringPrintf;
using std::ostream;
using std::string;
using std::unique_ptr;

namespace mist {

UsbInterfaceDescriptor::UsbInterfaceDescriptor(
    const base::WeakPtr<UsbDevice>& device,
    const libusb_interface_descriptor* interface_descriptor)
    : device_(device), interface_descriptor_(interface_descriptor) {
  CHECK(interface_descriptor_);
}

UsbInterfaceDescriptor::~UsbInterfaceDescriptor() {}

uint8_t UsbInterfaceDescriptor::GetLength() const {
  return interface_descriptor_->bLength;
}

uint8_t UsbInterfaceDescriptor::GetDescriptorType() const {
  return interface_descriptor_->bDescriptorType;
}

uint8_t UsbInterfaceDescriptor::GetInterfaceNumber() const {
  return interface_descriptor_->bInterfaceNumber;
}

uint8_t UsbInterfaceDescriptor::GetAlternateSetting() const {
  return interface_descriptor_->bAlternateSetting;
}

uint8_t UsbInterfaceDescriptor::GetNumEndpoints() const {
  return interface_descriptor_->bNumEndpoints;
}

uint8_t UsbInterfaceDescriptor::GetInterfaceClass() const {
  return interface_descriptor_->bInterfaceClass;
}

uint8_t UsbInterfaceDescriptor::GetInterfaceSubclass() const {
  return interface_descriptor_->bInterfaceSubClass;
}

uint8_t UsbInterfaceDescriptor::GetInterfaceProtocol() const {
  return interface_descriptor_->bInterfaceProtocol;
}

string UsbInterfaceDescriptor::GetInterfaceDescription() const {
  return device_ ? device_->GetStringDescriptorAscii(
                       interface_descriptor_->iInterface)
                 : string();
}

UsbEndpointDescriptor* UsbInterfaceDescriptor::GetEndpointDescriptor(
    uint8_t index) const {
  if (index >= GetNumEndpoints()) {
    LOG(ERROR) << StringPrintf(
        "Invalid endpoint index %d. Must be less than %d.", index,
        GetNumEndpoints());
    return nullptr;
  }

  return new UsbEndpointDescriptor(&interface_descriptor_->endpoint[index]);
}

UsbEndpointDescriptor*
UsbInterfaceDescriptor::GetEndpointDescriptorByTransferTypeAndDirection(
    UsbTransferType transfer_type, UsbDirection direction) const {
  for (uint8_t i = 0; i < GetNumEndpoints(); ++i) {
    unique_ptr<UsbEndpointDescriptor> endpoint_descriptor(
        GetEndpointDescriptor(i));
    if ((endpoint_descriptor->GetTransferType() == transfer_type) &&
        (endpoint_descriptor->GetDirection() == direction)) {
      return endpoint_descriptor.release();
    }
  }
  return nullptr;
}

string UsbInterfaceDescriptor::ToString() const {
  return StringPrintf(
      "Interface (Length=%u, "
      "DescriptorType=%u, "
      "InterfaceNumber=%u, "
      "AlternateSetting=%u, "
      "NumEndpoints=%u, "
      "InterfaceClass=%u, "
      "InterfaceSubclass=%u, "
      "InterfaceProtocol=%u, "
      "Interface='%s')",
      GetLength(), GetDescriptorType(), GetInterfaceNumber(),
      GetAlternateSetting(), GetNumEndpoints(), GetInterfaceClass(),
      GetInterfaceSubclass(), GetInterfaceProtocol(),
      GetInterfaceDescription().c_str());
}

}  // namespace mist

ostream& operator<<(ostream& stream,
                    const mist::UsbInterfaceDescriptor& interface_descriptor) {
  stream << interface_descriptor.ToString();
  return stream;
}
