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