// Copyright 2019 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 <ddktl/device.h>
#include <ddktl/protocol/usb/function.h>
#include <usb/request-cpp.h>
#include <usb/usb-request.h>

static constexpr size_t BULK_TX_COUNT = 16;
static constexpr size_t BULK_RX_COUNT = 16;
static constexpr size_t INTR_COUNT = 8;

static constexpr size_t BULK_MAX_PACKET = 512;  // FIXME(voydanoff) USB 3.0 support.
// FIXME(voydanoff) Increase this when DCI drivers support
// non-contiguous DMA buffers.
static constexpr size_t BULK_REQ_SIZE = 4096;
static constexpr size_t INTR_REQ_SIZE = 1024;
static constexpr size_t INTR_MAX_PACKET = 64;

namespace usb_function_test {

class UsbTest;
using UsbTestType = ddk::Device<UsbTest, ddk::UnbindableNew>;
class UsbTest : public UsbTestType, public ddk::UsbFunctionInterfaceProtocol<UsbTest> {
 public:
  explicit UsbTest(zx_device_t* parent) : UsbTestType(parent) {}
  zx_status_t Init();

  size_t UsbFunctionInterfaceGetDescriptorsSize() { return sizeof(descriptors_); }

  void UsbFunctionInterfaceGetDescriptors(void* buffer, size_t buffer_size, size_t* out_actual);

  zx_status_t UsbFunctionInterfaceControl(const usb_setup_t* setup, const void* write_buffer,
                                          size_t write_size, void* read_buffer, size_t read_size,
                                          size_t* out_read_actual);

  zx_status_t UsbFunctionInterfaceSetConfigured(bool configured, usb_speed_t speed);

  zx_status_t UsbFunctionInterfaceSetInterface(uint8_t interface, uint8_t alt_setting);

  void DdkUnbindNew(ddk::UnbindTxn txn);

  size_t UsbFunctionGetRequestSize() { return parent_req_size_ + sizeof(usb_req_internal_t); }

  void DdkRelease();
  static zx_status_t Create(void* ctx, zx_device_t* parent);

 private:
  void TestIntrComplete(usb_request_t* req);
  void TestBulkOutComplete(usb_request_t* req);
  void TestBulkInComplete(usb_request_t* req);
  ddk::UsbFunctionProtocolClient function_;

  // These are lists of usb_request_t.
  usb::RequestQueue<void> bulk_out_reqs_ __TA_GUARDED(lock_);
  usb::RequestQueue<void> bulk_in_reqs_ __TA_GUARDED(lock_);
  usb::RequestQueue<void> intr_reqs_ __TA_GUARDED(lock_);
  usb::RequestQueue<void> requests_;

  uint8_t test_data_[INTR_REQ_SIZE];
  size_t test_data_length_;

  bool configured_;

  fbl::Mutex lock_;

  uint8_t bulk_out_addr_;
  uint8_t bulk_in_addr_;
  uint8_t intr_addr_;
  size_t parent_req_size_;

  struct {
    usb_interface_descriptor_t intf;
    usb_endpoint_descriptor_t intr_ep;
    usb_endpoint_descriptor_t bulk_out_ep;
    usb_endpoint_descriptor_t bulk_in_ep;
  } descriptors_ = {
      .intf =
          {
              .bLength = sizeof(usb_interface_descriptor_t),
              .bDescriptorType = USB_DT_INTERFACE,
              .bInterfaceNumber = 0,  // set later
              .bAlternateSetting = 0,
              .bNumEndpoints = 3,
              .bInterfaceClass = USB_CLASS_VENDOR,
              .bInterfaceSubClass = 0,
              .bInterfaceProtocol = 0,
              .iInterface = 0,
          },
      .intr_ep =
          {
              .bLength = sizeof(usb_endpoint_descriptor_t),
              .bDescriptorType = USB_DT_ENDPOINT,
              .bEndpointAddress = 0,  // set later
              .bmAttributes = USB_ENDPOINT_INTERRUPT,
              .wMaxPacketSize = htole16(INTR_MAX_PACKET),
              .bInterval = 8,
          },
      .bulk_out_ep =
          {
              .bLength = sizeof(usb_endpoint_descriptor_t),
              .bDescriptorType = USB_DT_ENDPOINT,
              .bEndpointAddress = 0,  // set later
              .bmAttributes = USB_ENDPOINT_BULK,
              .wMaxPacketSize = htole16(BULK_MAX_PACKET),
              .bInterval = 0,
          },
      .bulk_in_ep =
          {
              .bLength = sizeof(usb_endpoint_descriptor_t),
              .bDescriptorType = USB_DT_ENDPOINT,
              .bEndpointAddress = 0,  // set later
              .bmAttributes = USB_ENDPOINT_BULK,
              .wMaxPacketSize = htole16(BULK_MAX_PACKET),
              .bInterval = 0,
          },
  };
};

}  // namespace usb_function_test
