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

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/usb.h>
#include <ddk/usb/usb.h>
#include <fbl/vector.h>
#include <stdlib.h>
#include <zircon/hw/usb-video.h>

#include "garnet/drivers/usb_video/usb-video-stream.h"
#include "garnet/drivers/usb_video/usb-video.h"
#include "garnet/drivers/usb_video/uvc_format.h"

namespace {
// The biggest size we are allowing USB descriptor strings to be.
// Technically, the bLength field for strings is one byte, so the
// max size for any string should be 255.
static constexpr size_t kUsbDescriptorStringSize = 512;

// Extract strings from the device description.
// Strings in the usb device description are represented as indices
// into the 'strings' section at the end.  This function unpacks a specific
// string, given its index.
std::string FetchString(const usb_protocol_t& usb_proto,
                        uint8_t description_index) {
  uint8_t str_buf[kUsbDescriptorStringSize];
  size_t buflen = sizeof(str_buf);
  uint16_t language_id = 0;
  zx_status_t res = usb_get_string_descriptor(&usb_proto, description_index,
                                              language_id, str_buf, buflen,
                                              &buflen, &language_id);
  if (res != ZX_OK) {
    return std::string();
  }

  buflen = std::min(buflen, sizeof(str_buf));
  return std::string(reinterpret_cast<char*>(str_buf), buflen);
}

// Extract vendor and product information from the USB device description.
video::usb::UsbDeviceInfo GetDeviceInfo(const usb_protocol_t& usb_proto) {
  usb_device_descriptor_t usb_dev_desc;
  video::usb::UsbDeviceInfo device_info;
  // Fetch our top level device descriptor, so we know stuff like the values
  // of our VID/PID.
  usb_get_device_descriptor(&usb_proto, &usb_dev_desc);
  device_info.vendor_id = usb_dev_desc.idVendor;
  device_info.product_id = usb_dev_desc.idProduct;
  // Attempt to fetch the string descriptors for our manufacturer name,
  // product name, and serial number.
  if (usb_dev_desc.iManufacturer) {
    device_info.manufacturer =
        FetchString(usb_proto, usb_dev_desc.iManufacturer);
  }

  if (usb_dev_desc.iProduct) {
    device_info.product_name = FetchString(usb_proto, usb_dev_desc.iProduct);
  }

  if (usb_dev_desc.iSerialNumber) {
    device_info.serial_number =
        FetchString(usb_proto, usb_dev_desc.iSerialNumber);
  }
  return device_info;
}

zx_status_t usb_video_parse_descriptors(void* ctx, zx_device_t* device,
                                        void** cookie) {
  usb_protocol_t usb;
  zx_status_t status = device_get_protocol(device, ZX_PROTOCOL_USB, &usb);
  if (status != ZX_OK) {
    return status;
  }

  // Grab the device information, so we can use it when creating the
  // UsbVideoStream.
  auto device_info = GetDeviceInfo(usb);

  usb_desc_iter_t iter;
  status = usb_desc_iter_init(&usb, &iter);
  if (status != ZX_OK) {
    return status;
  }

  int video_source_index = 0;
  video::usb::UvcFormatList formats;
  fbl::Vector<video::usb::UsbVideoStreamingSetting> streaming_settings;
  fbl::AllocChecker ac;

  usb_descriptor_header_t* header;
  // Most recent USB interface descriptor.
  usb_interface_descriptor_t* intf = NULL;
  // Most recent video control header.
  usb_video_vc_header_desc* control_header = NULL;
  // Most recent video streaming input header.
  usb_video_vs_input_header_desc* input_header = NULL;

  while ((header = usb_desc_iter_next(&iter)) != NULL) {
    switch (header->bDescriptorType) {
      case USB_DT_INTERFACE_ASSOCIATION: {
        usb_interface_assoc_descriptor_t* assoc_desc =
            (usb_interface_assoc_descriptor_t*)header;
        zxlogf(TRACE,
               "USB_DT_INTERFACE_ASSOCIATION bInterfaceCount: %u "
               "bFirstInterface: %u\n",
               assoc_desc->bInterfaceCount, assoc_desc->bFirstInterface);
        break;
      }
      case USB_DT_INTERFACE: {
        intf = (usb_interface_descriptor_t*)header;

        if (intf->bInterfaceClass == USB_CLASS_VIDEO) {
          if (intf->bInterfaceSubClass == USB_SUBCLASS_VIDEO_CONTROL) {
            zxlogf(TRACE, "interface USB_SUBCLASS_VIDEO_CONTROL\n");
            break;
          } else if (intf->bInterfaceSubClass == USB_SUBCLASS_VIDEO_STREAMING) {
            zxlogf(TRACE,
                   "interface USB_SUBCLASS_VIDEO_STREAMING bAlternateSetting: "
                   "%d\n",
                   intf->bAlternateSetting);
            // Encountered a new video streaming interface.
            if (intf->bAlternateSetting == 0) {
              // Create a video source if we've successfully parsed a VS
              // interface.
              if (formats.Size() > 0) {
                status = video::usb::UsbVideoStream::Create(
                    device, &usb, video_source_index++, intf, control_header,
                    input_header, std::move(formats), &streaming_settings,
                    std::move(device_info));
                if (status != ZX_OK) {
                  zxlogf(ERROR, "UsbVideoStream::Create failed: %d\n", status);
                  goto error_return;
                }
              }
              // formats.reset();  //TODO(garratt): what to do here?
              streaming_settings.reset();
              input_header = NULL;
            }
            break;
          } else if (intf->bInterfaceSubClass ==
                     USB_SUBCLASS_VIDEO_INTERFACE_COLLECTION) {
            zxlogf(TRACE,
                   "interface USB_SUBCLASS_VIDEO_INTERFACE_COLLECTION "
                   "bAlternateSetting: %d\n",
                   intf->bAlternateSetting);
            break;
          }
        }
        zxlogf(TRACE, "USB_DT_INTERFACE %d %d %d\n", intf->bInterfaceClass,
               intf->bInterfaceSubClass, intf->bInterfaceProtocol);
        break;
      }
      case USB_VIDEO_CS_INTERFACE: {
        usb_video_vc_desc_header* vc_header = (usb_video_vc_desc_header*)header;
        if (intf->bInterfaceSubClass == USB_SUBCLASS_VIDEO_CONTROL) {
          switch (vc_header->bDescriptorSubtype) {
            case USB_VIDEO_VC_HEADER: {
              control_header = (usb_video_vc_header_desc*)header;
              zxlogf(TRACE, "USB_VIDEO_VC_HEADER dwClockFrequency: %u\n",
                     control_header->dwClockFrequency);
              break;
            }
            case USB_VIDEO_VC_INPUT_TERMINAL: {
              usb_video_vc_input_terminal_desc* desc =
                  (usb_video_vc_input_terminal_desc*)header;
              zxlogf(TRACE, "USB_VIDEO_VC_INPUT_TERMINAL wTerminalType: %04X\n",
                     le16toh(desc->wTerminalType));
              break;
            }
            case USB_VIDEO_VC_OUTPUT_TERMINAL: {
              usb_video_vc_output_terminal_desc* desc =
                  (usb_video_vc_output_terminal_desc*)header;
              zxlogf(TRACE,
                     "USB_VIDEO_VC_OUTPUT_TERMINAL wTerminalType: %04X\n",
                     le16toh(desc->wTerminalType));
              break;
            }
            case USB_VIDEO_VC_SELECTOR_UNIT:
              zxlogf(TRACE, "USB_VIDEO_VC_SELECTOR_UNIT\n");
              break;
            case USB_VIDEO_VC_PROCESSING_UNIT:
              zxlogf(TRACE, "USB_VIDEO_VC_PROCESSING_UNIT\n");
              break;
            case USB_VIDEO_VC_EXTENSION_UNIT:
              zxlogf(TRACE, "USB_VIDEO_VS_EXTENSION_TYPE\n");
              break;
            case USB_VIDEO_VC_ENCODING_UNIT:
              zxlogf(TRACE, "USB_VIDEO_VS_ENCODING_TYPE\n");
              break;
          }
        } else if (intf->bInterfaceSubClass == USB_SUBCLASS_VIDEO_STREAMING) {
          switch (vc_header->bDescriptorSubtype) {
            case USB_VIDEO_VS_INPUT_HEADER: {
              input_header = (usb_video_vs_input_header_desc*)header;
              zxlogf(TRACE,
                     "USB_VIDEO_VS_INPUT_HEADER bNumFormats: %u "
                     "bEndpointAddress 0x%x\n",
                     input_header->bNumFormats, input_header->bEndpointAddress);
              break;
            }
            case USB_VIDEO_VS_OUTPUT_HEADER:
              zxlogf(TRACE, "USB_VIDEO_VS_OUTPUT_HEADER\n");
              break;
            case USB_VIDEO_VS_FORMAT_UNCOMPRESSED:
            case USB_VIDEO_VS_FORMAT_MJPEG:
            case USB_VIDEO_VS_FORMAT_MPEG2TS:
            case USB_VIDEO_VS_FORMAT_DV:
            case USB_VIDEO_VS_FORMAT_FRAME_BASED:
            case USB_VIDEO_VS_FORMAT_STREAM_BASED:
            case USB_VIDEO_VS_FORMAT_H264:
            case USB_VIDEO_VS_FORMAT_H264_SIMULCAST:
            case USB_VIDEO_VS_FORMAT_VP8:
            case USB_VIDEO_VS_FORMAT_VP8_SIMULCAST:
              if (formats.number_of_formats() >= input_header->bNumFormats) {
                // More formats than expected, this should never happen.
                zxlogf(
                    ERROR,
                    "skipping unexpected format %u, already have %d formats\n",
                    vc_header->bDescriptorSubtype, input_header->bNumFormats);
                break;
              }
              status = formats.ParseUsbDescriptor(vc_header, &iter);
              if (status == ZX_ERR_NO_MEMORY) {
                goto error_return;
              }
              // ParseUsbDescriptor will return an error if it's an unsupported
              // format, but we shouldn't return early in case the device has
              // other formats we support.
              break;
          }
        } else if (intf->bInterfaceSubClass ==
                   USB_SUBCLASS_VIDEO_INTERFACE_COLLECTION) {
          zxlogf(TRACE, "USB_SUBCLASS_VIDEO_INTERFACE_COLLECTION\n");
        }
        break;
      }
      case USB_DT_ENDPOINT: {
        usb_endpoint_descriptor_t* endp = (usb_endpoint_descriptor_t*)header;
        const char* direction =
            (endp->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN
                ? "IN"
                : "OUT";
        uint16_t max_packet_size = usb_ep_max_packet(endp);
        // The additional transactions per microframe value is extracted
        // from bits 12..11 of wMaxPacketSize, so it fits in a uint8_t.
        uint8_t per_mf =
            static_cast<uint8_t>(usb_ep_add_mf_transactions(endp) + 1);
        zxlogf(TRACE,
               "USB_DT_ENDPOINT %s bEndpointAddress 0x%x packet size %d, %d / "
               "mf\n",
               direction, endp->bEndpointAddress, max_packet_size, per_mf);

        // There may be another still image endpoint, so check the address
        // matches the input header.
        if (input_header &&
            endp->bEndpointAddress == input_header->bEndpointAddress) {
          video::usb::UsbVideoStreamingSetting setting = {
              .alt_setting = intf->bAlternateSetting,
              .transactions_per_microframe = per_mf,
              .max_packet_size = max_packet_size,
              .ep_type = usb_ep_type(endp)};
          streaming_settings.push_back(setting, &ac);
          if (!ac.check()) {
            status = ZX_ERR_NO_MEMORY;
            goto error_return;
          }
        }
        break;
      }
      case USB_VIDEO_CS_ENDPOINT: {
        usb_video_vc_interrupt_endpoint_desc* desc =
            (usb_video_vc_interrupt_endpoint_desc*)header;
        zxlogf(TRACE, "USB_VIDEO_CS_ENDPOINT wMaxTransferSize %u\n",
               desc->wMaxTransferSize);
        break;
      }
      case USB_DT_SS_EP_COMPANION: {
        if (streaming_settings.is_empty()) {
          status = ZX_ERR_BAD_STATE;
          goto error_return;
        }
        auto& settings = streaming_settings[streaming_settings.size() - 1];

        if (settings.ep_type == USB_ENDPOINT_ISOCHRONOUS) {
          usb_ss_ep_comp_descriptor_t* desc =
              (usb_ss_ep_comp_descriptor_t*)header;
          if (usb_ss_ep_comp_isoc_comp(desc)) {
            auto next = usb_desc_iter_next(&iter);
            if (next == nullptr ||
                next->bDescriptorType != USB_DT_SS_ISOCH_EP_COMPANION) {
              status = ZX_ERR_BAD_STATE;
              goto error_return;
            }
            usb_ss_isoch_ep_comp_descriptor_t* next_desc =
                (usb_ss_isoch_ep_comp_descriptor_t*)next;
            uint32_t denom = (desc->bMaxBurst + 1) * settings.max_packet_size;
            settings.transactions_per_microframe =
                (uint8_t)((next_desc->dwBytesPerInterval + denom - 1) / denom);
          } else {
            settings.transactions_per_microframe = (uint8_t)(
                (desc->bMaxBurst + 1) * (usb_ss_ep_comp_isoc_mult(desc) + 1));
          }
          break;
        }
        // fall through for unhandled superspeed bulk endpoint
      }
      default:
        zxlogf(TRACE, "unknown DT %d\n", header->bDescriptorType);
        break;
    }
  }
  if (formats.Size() > 0) {
    status = video::usb::UsbVideoStream::Create(
        device, &usb, video_source_index++, intf, control_header, input_header,
        std::move(formats), &streaming_settings, std::move(device_info));
    if (status != ZX_OK) {
      zxlogf(ERROR, "UsbVideoStream::Create failed: %d\n", status);
    }
  }
error_return:
  usb_desc_iter_release(&iter);
  return status;
}

}  // namespace

extern "C" zx_status_t usb_video_bind(void* ctx, zx_device_t* device,
                                      void** cookie) {
  return usb_video_parse_descriptors(ctx, device, cookie);
}
