// 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 "two-endpoint-hid-function.h"

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zircon/device/usb-peripheral.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>

#include <memory>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/driver.h>
#include <ddk/metadata.h>
#include <ddk/platform-defs.h>
#include <fbl/algorithm.h>
#include <usb/usb-request.h>

constexpr int BULK_MAX_PACKET = 512;

namespace two_endpoint_hid_function {

static const uint8_t boot_mouse_r_desc[50] = {
    0x05, 0x01,  // Usage Page (Generic Desktop Ctrls)
    0x09, 0x02,  // Usage (Mouse)
    0xA1, 0x01,  // Collection (Application)
    0x09, 0x01,  //   Usage (Pointer)
    0xA1, 0x00,  //   Collection (Physical)
    0x05, 0x09,  //     Usage Page (Button)
    0x19, 0x01,  //     Usage Minimum (0x01)
    0x29, 0x03,  //     Usage Maximum (0x03)
    0x15, 0x00,  //     Logical Minimum (0)
    0x25, 0x01,  //     Logical Maximum (1)
    0x95, 0x03,  //     Report Count (3)
    0x75, 0x01,  //     Report Size (1)
    0x81, 0x02,  //     Input (Data,Var,Abs,No Wrap,Linear,No Null Position)
    0x95, 0x01,  //     Report Count (1)
    0x75, 0x05,  //     Report Size (5)
    0x81, 0x03,  //     Input (Const,Var,Abs,No Wrap,Linear,No Null Position)
    0x05, 0x01,  //     Usage Page (Generic Desktop Ctrls)
    0x09, 0x30,  //     Usage (X)
    0x09, 0x31,  //     Usage (Y)
    0x15, 0x81,  //     Logical Minimum (-127)
    0x25, 0x7F,  //     Logical Maximum (127)
    0x75, 0x08,  //     Report Size (8)
    0x95, 0x02,  //     Report Count (2)
    0x81, 0x06,  //     Input (Data,Var,Rel,No Wrap,Linear,No Null Position)
    0xC0,        //   End Collection
    0xC0,        // End Collection
};

size_t FakeUsbHidFunction::UsbFunctionInterfaceGetDescriptorsSize(void* ctx) {
  FakeUsbHidFunction* func = static_cast<FakeUsbHidFunction*>(ctx);
  return func->descriptor_size_;
}

void FakeUsbHidFunction::UsbFunctionInterfaceGetDescriptors(void* ctx, void* out_descriptors_buffer,
                                                            size_t descriptors_size,
                                                            size_t* out_descriptors_actual) {
  FakeUsbHidFunction* func = static_cast<FakeUsbHidFunction*>(ctx);
  memcpy(out_descriptors_buffer, func->descriptor_.get(),
         std::min(descriptors_size, func->descriptor_size_));
  *out_descriptors_actual = func->descriptor_size_;
}

zx_status_t FakeUsbHidFunction::UsbFunctionInterfaceControl(void* ctx, const usb_setup_t* setup,
                                                            const void* write_buffer,
                                                            size_t write_size,
                                                            void* out_read_buffer, size_t read_size,
                                                            size_t* out_read_actual) {
  FakeUsbHidFunction* func = static_cast<FakeUsbHidFunction*>(ctx);

  fbl::AutoLock lock(&func->mtx_);

  if (setup->bmRequestType == (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE)) {
    if (setup->bRequest == USB_REQ_GET_DESCRIPTOR) {
      memcpy(out_read_buffer, func->report_desc_.data(), func->report_desc_.size());
      *out_read_actual = func->report_desc_.size();
      return ZX_OK;
    }
  }
  if (setup->bmRequestType == (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) {
    if (setup->bRequest == USB_HID_GET_REPORT) {
      memcpy(out_read_buffer, func->report_.data(), func->report_.size());
      *out_read_actual = func->report_.size();
      return ZX_OK;
    }
    if (setup->bRequest == USB_HID_GET_PROTOCOL) {
      memcpy(out_read_buffer, &func->hid_protocol_, sizeof(func->hid_protocol_));
      *out_read_actual = sizeof(func->hid_protocol_);
      return ZX_OK;
    }
  }
  if (setup->bmRequestType == (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) {
    if (setup->bRequest == USB_HID_SET_REPORT) {
      memcpy(func->report_.data(), write_buffer, func->report_.size());
      return ZX_OK;
    }
    if (setup->bRequest == USB_HID_SET_PROTOCOL) {
      func->hid_protocol_ = static_cast<uint8_t>(setup->wValue);
      return ZX_OK;
    }
  }
  return ZX_ERR_IO_REFUSED;
}

zx_status_t FakeUsbHidFunction::UsbFunctionInterfaceSetConfigured(void* ctx, bool configured,
                                                                  usb_speed_t speed) {
  return ZX_OK;
}
zx_status_t FakeUsbHidFunction::UsbFunctionInterfaceSetInterface(void* ctx, uint8_t interface,
                                                                 uint8_t alt_setting) {
  return ZX_OK;
}

int FakeUsbHidFunction::Thread() {
  while (1) {
    fbl::AutoLock lock(&mtx_);
    if (!data_out_req_complete_) {
      event_.Wait(&mtx_);
    }

    if (!active_) {
      return 0;
    }

    data_out_req_complete_ = false;
    // Release the lock before queueing, as the callback acquires the lock and is sometimes run in
    // the same thread.
    lock.release();
    usb_request_complete_t complete = {
        .callback =
            [](void* ctx, usb_request_t* req) {
              return static_cast<FakeUsbHidFunction*>(ctx)->UsbEndpointOutCallback(req);
            },
        .ctx = this,
    };
    function_.RequestQueue(data_out_req_->request(), &complete);
  }
  return 0;
}

zx_status_t FakeUsbHidFunction::Bind() {
  fbl::AutoLock lock(&mtx_);
  report_desc_.resize(sizeof(boot_mouse_r_desc));
  memcpy(report_desc_.data(), &boot_mouse_r_desc, sizeof(boot_mouse_r_desc));
  report_.resize(3);

  descriptor_size_ = sizeof(fake_usb_hid_descriptor_t) + sizeof(usb_hid_descriptor_entry_t);
  descriptor_.reset(static_cast<fake_usb_hid_descriptor_t*>(calloc(1, descriptor_size_)));
  descriptor_->interface = {
      .bLength = sizeof(usb_interface_descriptor_t),
      .bDescriptorType = USB_DT_INTERFACE,
      .bInterfaceNumber = 0,
      .bAlternateSetting = 0,
      .bNumEndpoints = 1,
      .bInterfaceClass = USB_CLASS_HID,
      .bInterfaceSubClass = USB_HID_SUBCLASS_BOOT,
      .bInterfaceProtocol = USB_HID_PROTOCOL_MOUSE,
      .iInterface = 0,
  };
  descriptor_->interrupt_in = {
      .bLength = sizeof(usb_endpoint_descriptor_t),
      .bDescriptorType = USB_DT_ENDPOINT,
      .bEndpointAddress = USB_ENDPOINT_IN,  // set later
      .bmAttributes = USB_ENDPOINT_INTERRUPT,
      .wMaxPacketSize = htole16(BULK_MAX_PACKET),
      .bInterval = 8,
  };
  descriptor_->interrupt_out = {
      .bLength = sizeof(usb_endpoint_descriptor_t),
      .bDescriptorType = USB_DT_ENDPOINT,
      .bEndpointAddress = USB_ENDPOINT_OUT,  // set later
      .bmAttributes = USB_ENDPOINT_INTERRUPT,
      .wMaxPacketSize = htole16(BULK_MAX_PACKET),
      .bInterval = 8,
  };
  descriptor_->hid_descriptor = {
      .bLength = sizeof(usb_hid_descriptor_t) + sizeof(usb_hid_descriptor_entry_t),
      .bDescriptorType = USB_DT_HID,
      .bcdHID = 0,
      .bCountryCode = 0,
      .bNumDescriptors = 1,
  };
  descriptor_->hid_descriptor.descriptors[0] = {
      .bDescriptorType = 0x22,  // HID TYPE REPORT
      .wDescriptorLength = static_cast<uint16_t>(report_desc_.size()),
  };

  zx_status_t status = function_.AllocInterface(&descriptor_->interface.bInterfaceNumber);
  if (status != ZX_OK) {
    zxlogf(ERROR, "FakeUsbHidFunction: usb_function_alloc_interface failed");
    return status;
  }
  status = function_.AllocEp(USB_DIR_IN, &descriptor_->interrupt_in.bEndpointAddress);
  if (status != ZX_OK) {
    zxlogf(ERROR, "FakeUsbHidFunction: usb_function_alloc_ep for endpoint in failed");
    return status;
  }
  status = function_.AllocEp(USB_DIR_OUT, &descriptor_->interrupt_out.bEndpointAddress);
  if (status != ZX_OK) {
    zxlogf(ERROR, "FakeUsbHidFunction: usb_function_alloc_ep for endpoint out failed");
    return status;
  }

  status = usb::Request<>::Alloc(&data_out_req_, BULK_MAX_PACKET,
                                 descriptor_->interrupt_out.bEndpointAddress,
                                 function_.GetRequestSize());
  if (status != ZX_OK) {
    return status;
  }

  active_ = true;
  thrd_create(
      &thread_, [](void* ctx) { return static_cast<FakeUsbHidFunction*>(ctx)->Thread(); }, this);

  status = DdkAdd("usb-hid-function");
  if (status != ZX_OK) {
    return status;
  }
  function_.SetInterface(this, &function_interface_ops_);
  return ZX_OK;
}

void FakeUsbHidFunction::DdkUnbind(ddk::UnbindTxn txn) {
  {
    fbl::AutoLock lock(&mtx_);
    active_ = false;
    event_.Signal();
  }

  int retval;
  thrd_join(thread_, &retval);
  txn.Reply();
}

void FakeUsbHidFunction::DdkRelease() { delete this; }

zx_status_t bind(void* ctx, zx_device_t* parent) {
  auto dev = std::make_unique<FakeUsbHidFunction>(parent);
  zx_status_t status = dev->Bind();
  if (status == ZX_OK) {
    // devmgr is now in charge of the memory for dev
    dev.release();
  }
  return ZX_OK;
}

void FakeUsbHidFunction::UsbEndpointOutCallback(usb_request_t* request) {
  fbl::AutoLock lock(&mtx_);
  if (request->response.status == ZX_OK) {
    report_.resize(request->response.actual);
    size_t result = usb_request_copy_from(request, report_.data(), report_.size(), 0);
    ZX_ASSERT(result == request->response.actual);
  } else {
    zxlogf(ERROR, "request status: %d", request->response.status);
    active_ = false;
  }
  data_out_req_complete_ = true;
  event_.Signal();
}

static constexpr zx_driver_ops_t two_endpoint_hid_driver_ops = []() {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.bind = bind;
  return ops;
}();

}  // namespace two_endpoint_hid_function

// clang-format off
ZIRCON_DRIVER_BEGIN(two_endpoint_hid_function, two_endpoint_hid_function::two_endpoint_hid_driver_ops, "zircon", "0.1", 3)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_USB_FUNCTION),
    BI_ABORT_IF(NE, BIND_USB_CLASS, USB_CLASS_HID),
    BI_MATCH_IF(EQ, BIND_USB_PROTOCOL, USB_PROTOCOL_TEST_HID_TWO_ENDPOINT),
ZIRCON_DRIVER_END(two_endpoint_hid_function)
    // clang-format on
