// 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 <assert.h>
#include <fuchsia/hardware/usb/function/cpp/banjo.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zircon/device/usb-peripheral.h>
#include <zircon/hw/usb/hid.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>

#include <atomic>
#include <memory>
#include <vector>

#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/metadata.h>
#include <ddk/platform-defs.h>
#include <ddktl/device.h>
#include <fbl/algorithm.h>
#include <fbl/condition_variable.h>
#include <fbl/mutex.h>
#include <usb/request-cpp.h>
#include <usb/usb-request.h>

#include "src/devices/serial/drivers/ftdi/ftdi_function_bind.h"

#define BULK_MAX_PACKET 512
#define FTDI_STATUS_SIZE 2

namespace fake_ftdi_function {

class FakeFtdiFunction;
using DeviceType = ddk::Device<FakeFtdiFunction, ddk::Unbindable>;
class FakeFtdiFunction : public DeviceType {
 public:
  FakeFtdiFunction(zx_device_t* parent) : DeviceType(parent), function_(parent) {}
  zx_status_t Bind();
  // |ddk::Device|
  void DdkUnbind(ddk::UnbindTxn txn);
  // |ddk::Device|
  void DdkRelease();

  static size_t UsbFunctionInterfaceGetDescriptorsSize(void* ctx);

  static void UsbFunctionInterfaceGetDescriptors(void* ctx, uint8_t* out_descriptors_buffer,
                                                 size_t descriptors_size,
                                                 size_t* out_descriptors_actual);
  static zx_status_t UsbFunctionInterfaceControl(void* ctx, const usb_setup_t* setup,
                                                 const uint8_t* write_buffer, size_t write_size,
                                                 uint8_t* out_read_buffer, size_t read_size,
                                                 size_t* out_read_actual);
  static zx_status_t UsbFunctionInterfaceSetConfigured(void* ctx, bool configured,
                                                       usb_speed_t speed);
  static zx_status_t UsbFunctionInterfaceSetInterface(void* ctx, uint8_t interface,
                                                      uint8_t alt_setting);

 private:
  int Thread();
  void DataInComplete() TA_REQ(mtx_);
  void DataOutComplete() TA_REQ(mtx_);
  void RequestQueue(usb_request_t* req, const usb_request_complete_t* completion);
  void CompletionCallback(usb_request_t* req);

  usb_function_interface_protocol_ops_t function_interface_ops_{
      .get_descriptors_size = UsbFunctionInterfaceGetDescriptorsSize,
      .get_descriptors = UsbFunctionInterfaceGetDescriptors,
      .control = UsbFunctionInterfaceControl,
      .set_configured = UsbFunctionInterfaceSetConfigured,
      .set_interface = UsbFunctionInterfaceSetInterface,
  };
  ddk::UsbFunctionProtocolClient function_;

  struct fake_ftdi_descriptor_t {
    usb_interface_descriptor_t interface;
    usb_endpoint_descriptor_t bulk_in;
    usb_endpoint_descriptor_t bulk_out;
  } __PACKED descriptor_;

  size_t descriptor_size_ = 0;

  size_t parent_req_size_ = 0;
  uint8_t bulk_out_addr_ = 0;
  uint8_t bulk_in_addr_ = 0;

  std::optional<usb::Request<>> data_in_req_ TA_GUARDED(mtx_);
  bool data_in_req_complete_ TA_GUARDED(mtx_) = false;

  std::optional<usb::Request<>> data_out_req_ TA_GUARDED(mtx_);
  bool data_out_req_complete_ TA_GUARDED(mtx_) = false;

  fbl::ConditionVariable event_ TA_GUARDED(mtx_);
  fbl::Mutex mtx_;

  bool configured_ = false;
  bool active_ = false;
  thrd_t thread_ = {};
  std::atomic<int> pending_request_count_;
};

void FakeFtdiFunction::CompletionCallback(usb_request_t* req) {
  fbl::AutoLock lock(&mtx_);
  if (req == data_in_req_->request()) {
    data_in_req_complete_ = true;
  } else if (req == data_out_req_->request()) {
    data_out_req_complete_ = true;
  }
  event_.Signal();
}

void FakeFtdiFunction::RequestQueue(usb_request_t* req, const usb_request_complete_t* completion) {
  atomic_fetch_add(&pending_request_count_, 1);
  function_.RequestQueue(req, completion);
}

void FakeFtdiFunction::DataInComplete() {}

void FakeFtdiFunction::DataOutComplete() {
  if (data_out_req_->request()->response.status != ZX_OK) {
    return;
  }
  std::vector<uint8_t> data(data_out_req_->request()->response.actual);
  // std::vector should zero-initialize
  __UNUSED size_t copied =
      usb_request_copy_from(data_out_req_->request(), data.data(), data.size(), 0);

  usb_request_complete_t complete = {
      .callback =
          [](void* ctx, usb_request_t* req) {
            return static_cast<FakeFtdiFunction*>(ctx)->CompletionCallback(req);
          },
      .ctx = this,
  };

  // Queue up another write.
  RequestQueue(data_out_req_->request(), &complete);

  // Queue up exact same read data. The first FTDI_STATUS_SIZE bytes should
  // be left alone.
  data_in_req_->request()->header.length = data.size() + FTDI_STATUS_SIZE;
  data_in_req_->request()->header.ep_address = bulk_in_addr_;

  copied = data_in_req_->CopyTo(data.data(), data.size(), FTDI_STATUS_SIZE);

  RequestQueue(data_in_req_->request(), &complete);
}

int FakeFtdiFunction::Thread() {
  while (1) {
    fbl::AutoLock lock(&mtx_);
    if (!(data_in_req_complete_ || data_out_req_complete_ || (!active_))) {
      event_.Wait(&mtx_);
    }
    if (!active_ && !atomic_load(&pending_request_count_)) {
      return 0;
    }
    if (data_in_req_complete_) {
      atomic_fetch_add(&pending_request_count_, -1);
      data_in_req_complete_ = false;
      DataInComplete();
    }
    if (data_out_req_complete_) {
      atomic_fetch_add(&pending_request_count_, -1);
      data_out_req_complete_ = false;
      DataOutComplete();
    }
  }
  return 0;
}

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

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

zx_status_t FakeFtdiFunction::UsbFunctionInterfaceControl(
    void* ctx, const usb_setup_t* setup, const uint8_t* write_buffer, size_t write_size,
    uint8_t* out_read_buffer, size_t read_size, size_t* out_read_actual) {
  if (out_read_actual) {
    *out_read_actual = 0;
  }
  return ZX_OK;
}

zx_status_t FakeFtdiFunction::UsbFunctionInterfaceSetConfigured(void* ctx, bool configured,
                                                                usb_speed_t speed) {
  FakeFtdiFunction* func = static_cast<FakeFtdiFunction*>(ctx);
  fbl::AutoLock lock(&func->mtx_);
  zx_status_t status;

  if (configured) {
    if (func->configured_) {
      return ZX_OK;
    }
    func->configured_ = true;

    if ((status = func->function_.ConfigEp(&func->descriptor_.bulk_in, nullptr)) != ZX_OK ||
        (status = func->function_.ConfigEp(&func->descriptor_.bulk_out, nullptr)) != ZX_OK) {
      zxlogf(ERROR, "ftdi-function: usb_function_config_ep failed");
    }
    // queue first read on OUT endpoint
    usb_request_complete_t complete = {
        .callback =
            [](void* ctx, usb_request_t* req) {
              return static_cast<FakeFtdiFunction*>(ctx)->CompletionCallback(req);
            },
        .ctx = ctx,
    };
    zxlogf(INFO, "ftdi-function: about to configure!");
    if (func->data_out_req_) {
      zxlogf(INFO, "We have data out!");
    }
    func->RequestQueue(func->data_out_req_->request(), &complete);
  } else {
    func->configured_ = false;
  }
  return ZX_OK;
}

zx_status_t FakeFtdiFunction::UsbFunctionInterfaceSetInterface(void* ctx, uint8_t interface,
                                                               uint8_t alt_setting) {
  return ZX_OK;
}

zx_status_t FakeFtdiFunction::Bind() {
  fbl::AutoLock lock(&mtx_);

  descriptor_size_ = sizeof(descriptor_);
  descriptor_.interface = {
      .bLength = sizeof(usb_interface_descriptor_t),
      .bDescriptorType = USB_DT_INTERFACE,
      .bInterfaceNumber = 0,
      .bAlternateSetting = 0,
      .bNumEndpoints = 2,
      .bInterfaceClass = 0xFF,
      .bInterfaceSubClass = 0xFF,
      .bInterfaceProtocol = 0xFF,
      .iInterface = 0,
  };
  descriptor_.bulk_in = {
      .bLength = sizeof(usb_endpoint_descriptor_t),
      .bDescriptorType = USB_DT_ENDPOINT,
      .bEndpointAddress = USB_ENDPOINT_IN,  // set later
      .bmAttributes = USB_ENDPOINT_BULK,
      .wMaxPacketSize = htole16(BULK_MAX_PACKET),
      .bInterval = 0,
  };
  descriptor_.bulk_out = {
      .bLength = sizeof(usb_endpoint_descriptor_t),
      .bDescriptorType = USB_DT_ENDPOINT,
      .bEndpointAddress = USB_ENDPOINT_OUT,  // set later
      .bmAttributes = USB_ENDPOINT_BULK,
      .wMaxPacketSize = htole16(BULK_MAX_PACKET),
      .bInterval = 0,
  };

  active_ = true;
  atomic_init(&pending_request_count_, 0);

  parent_req_size_ = function_.GetRequestSize();

  zx_status_t status = function_.AllocInterface(&descriptor_.interface.bInterfaceNumber);
  if (status != ZX_OK) {
    zxlogf(ERROR, "FakeFtdiFunction: usb_function_alloc_interface failed");
    return status;
  }
  status = function_.AllocEp(USB_DIR_IN, &descriptor_.bulk_in.bEndpointAddress);
  if (status != ZX_OK) {
    zxlogf(ERROR, "FakeFtdiFunction: usb_function_alloc_ep failed");
    return status;
  }
  status = function_.AllocEp(USB_DIR_OUT, &descriptor_.bulk_out.bEndpointAddress);
  if (status != ZX_OK) {
    zxlogf(ERROR, "FakeFtdiFunction: usb_function_alloc_ep failed");
    return status;
  }

  bulk_in_addr_ = descriptor_.bulk_in.bEndpointAddress;
  bulk_out_addr_ = descriptor_.bulk_out.bEndpointAddress;

  status = usb::Request<>::Alloc(&data_out_req_, BULK_MAX_PACKET, bulk_out_addr_, parent_req_size_);
  if (status != ZX_OK) {
    return status;
  }
  status = usb::Request<>::Alloc(&data_in_req_, BULK_MAX_PACKET, bulk_in_addr_, parent_req_size_);
  if (status != ZX_OK) {
    return status;
  }

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

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

  return ZX_OK;
}

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

  int retval;
  thrd_join(thread_, &retval);

  txn.Reply();
}

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

zx_status_t bind(void* ctx, zx_device_t* parent) {
  auto dev = std::make_unique<FakeFtdiFunction>(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;
}
static constexpr zx_driver_ops_t driver_ops = []() {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.bind = bind;
  return ops;
}();

}  // namespace fake_ftdi_function

ZIRCON_DRIVER(ftdi_function, fake_ftdi_function::driver_ops, "zircon", "0.1");
