// Copyright 2020 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 "src/devices/usb/tests/usb-hci-test/usb-hci-test-driver.h"

#include <fuchsia/hardware/usb/c/banjo.h>
#include <lib/ddk/binding_driver.h>
#include <lib/ddk/debug.h>
#include <lib/ddk/device.h>
#include <lib/fit/defer.h>
#include <lib/sync/completion.h>
#include <lib/zx/vmo.h>
#include <unistd.h>
#include <zircon/process.h>

#include <limits>
#include <memory>

#include <fbl/algorithm.h>
#include <usb/peripheral.h>
#include <usb/request-cpp.h>
#include <usb/usb.h>

namespace usb {

void HciTest::Run(RunCompleter::Sync& completer) {
  if (test_running_) {
    completer.ReplyError(ZX_ERR_CONNECTION_REFUSED);
    return;
  }
  test_thread_.emplace(
      [this, completion = completer.ToAsync()]() mutable { TestThread(std::move(completion)); });
}

void HciTest::TestThread(RunCompleter::Async completer) {
  test_running_ = true;
  auto test_complete = fit::defer([this]() { test_running_ = false; });
  zx_status_t status = ZX_OK;
  fuchsia_hardware_usb_hcitest::wire::TestResults test_results;
  using Request = usb::CallbackRequest<sizeof(std::max_align_t) * 4>;
  size_t parent_size = usb_.GetRequestSize();
  bool running = true;
  uint64_t host_packets = 0;
  // Test recovery from CancelAll
  // TODO(https://fxbug.dev/42109089): Add asserts on every CancelAll when the rewrite goes in.
  usb_.CancelAll(bulk_out_.b_endpoint_address);
  struct {
    uint64_t start;
    uint64_t end;
    uint64_t bulk_in_packets;
    uint64_t bulk_out_packets;
  } results;
  enum UsbTesterCommand {
    StartTransfers = 0xE2,
    StopTransfers = 0xE3,
    StartShortPacketTests = 0xE4,
  };
  size_t actual;
  status = usb_.ControlOut(USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, StartShortPacketTests,
                           0, 0, ZX_TIME_INFINITE, nullptr, 0);
  bool correct_byte_count = true;
  if (status == ZX_OK) {
    {
      std::optional<Request> request;
      sync_completion_t completion;
      size_t bytes;
      Request::Alloc(&request, (4096 * 3) + 1024, bulk_in_.b_endpoint_address, parent_size,
                     [&bytes, &completion](Request request) {
                       bytes = request.request()->response.actual;
                       sync_completion_signal(&completion);
                     });
      request->Queue(usb_);
      sync_completion_wait(&completion, ZX_TIME_INFINITE);
      // First packet
      correct_byte_count &= bytes == 20;
    }
    {
      std::optional<Request> request;
      sync_completion_t completion;
      size_t bytes;
      Request::Alloc(&request, (4096 * 3) + 1024, bulk_in_.b_endpoint_address, parent_size,
                     [&bytes, &completion](Request request) {
                       bytes = request.request()->response.actual;
                       sync_completion_signal(&completion);
                     });
      request->Queue(usb_);
      sync_completion_wait(&completion, ZX_TIME_INFINITE);
      // Middle packet
      correct_byte_count &= bytes == 4098;
    }
    {
      std::optional<Request> request;
      sync_completion_t completion;
      size_t bytes;
      Request::Alloc(&request, (4096 * 3) + 1024, bulk_in_.b_endpoint_address, parent_size,
                     [&bytes, &completion](Request request) {
                       bytes = request.request()->response.actual;
                       sync_completion_signal(&completion);
                     });
      request->Queue(usb_);
      sync_completion_wait(&completion, ZX_TIME_INFINITE);
      // Last packet
      correct_byte_count &= bytes == (4096 * 3) + 511;
    }
    {
      // Validate correctness (run test 512 times to create TRB loops)
      for (size_t i = 0; i < 512; i++) {
        std::optional<Request> request;
        sync_completion_t completion;
        size_t bytes;
        Request::Alloc(&request, (4096 * 3) + 1024, bulk_in_.b_endpoint_address, parent_size,
                       [&bytes, &completion](Request request) {
                         bytes = request.request()->response.actual;
                         uint32_t* val;
                         request.Mmap(reinterpret_cast<void**>(&val));
                         for (size_t i = 0; i < ((4096 * 3) / 4); i++) {
                           if (val[i] != i) {
                             bytes = 0;
                           }
                         }
                         sync_completion_signal(&completion);
                       });
        request->Queue(usb_);
        sync_completion_wait(&completion, ZX_TIME_INFINITE);
        sync_completion_reset(&completion);
        // Last packet
        correct_byte_count &= bytes == (4096 * 3) + 511;
      }
    }
    {
      // Validate correctness (run test 512 times to create TRB loops)
      for (size_t i = 0; i < 512; i++) {
        std::optional<Request> request;
        sync_completion_t completion;
        size_t bytes;
        Request::Alloc(&request, (4096 * 3) + 1024, bulk_in_.b_endpoint_address, parent_size,
                       [&bytes, &completion](Request request) {
                         bytes = request.request()->response.actual;
                         uint32_t* val;
                         request.Mmap(reinterpret_cast<void**>(&val));
                         for (size_t i = 0; i < ((4096 * 3) / 4); i++) {
                           if (val[i] != i) {
                             bytes = 0;
                           }
                         }
                         sync_completion_signal(&completion);
                       });
        request->Queue(usb_);
        sync_completion_wait(&completion, ZX_TIME_INFINITE);
        sync_completion_reset(&completion);
        // Last packet
        correct_byte_count &= bytes == (4096 * 3) + 511;
      }
    }
    status = usb_.ControlIn(USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE, StopTransfers, 0, 0,
                            ZX_TIME_INFINITE, reinterpret_cast<uint8_t*>(&results), sizeof(results),
                            &actual);
  } else {
    usb_.ResetEndpoint(0);
  }

  for (size_t i = 0; i < 4096; i++) {
    std::optional<Request> request;
    Request::Alloc(&request, 8192, bulk_out_.b_endpoint_address, parent_size,
                   [&running, this, &host_packets](Request request) {
                     if (!running) {
                       return;
                     }
                     Request::Queue(std::move(request), usb_);
                     host_packets++;
                   });
    request->request()->direct = true;
    request->request()->header.length = usb_ep_max_packet(&bulk_out_);
    Request::Queue(std::move(*request), usb_);
  }
  // E2 start, E3 stop
  usb_.ControlOut(USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, StartTransfers, 0, 0,
                  ZX_TIME_INFINITE, nullptr, 0);
  constexpr auto kTestRuntime = 15;
  sleep(kTestRuntime);
  running = false;
  usb_.CancelAll(bulk_out_.b_endpoint_address);
  // Test the case where we haven't queued any data
  usb_.CancelAll(bulk_out_.b_endpoint_address);
  status = usb_.ControlIn(USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE, StopTransfers, 0, 0,
                          ZX_TIME_INFINITE, reinterpret_cast<uint8_t*>(&results), sizeof(results),
                          &actual);
  if (status != ZX_OK) {
    completer.ReplyError(status);
    return;
  }
  test_results.received_bulk_packets = host_packets;
  uint64_t clock_val = 0;
  uint64_t dropped_packets = 0;
  uint64_t isoch_packets = 0;
  // Timestamp in 125 microsecond intervals
  // TODO(https://fxbug.dev/42109822): Run isochronous test under load (at the same time as bulk)
  // once we get scheduling issues fixed.
  uint64_t timestamp = (usb_.GetCurrentFrame() + 20) * 8;
  running = true;
  // 8 transfers per millisecond (at rate of 125 microseconds per transfer)
  // We batch 5 1 millisecond transfers at a time.
  for (size_t i = 0; i < 8 * 5; i++) {
    std::optional<Request> request;
    Request::Alloc(&request, isoch_in_.w_max_packet_size, isoch_in_.b_endpoint_address, parent_size,
                   [&isoch_packets, &clock_val, &dropped_packets, &timestamp, &running,
                    this](Request request) {
                     if (!running) {
                       return;
                     }
                     isoch_packets++;
                     if (clock_val == 0) {
                       [[maybe_unused]] auto copy_result =
                           request.CopyFrom(&clock_val, sizeof(clock_val), 0);
                     } else {
                       uint64_t device_val = 0;
                       [[maybe_unused]] auto copy_result =
                           request.CopyFrom(&device_val, sizeof(device_val), 0);
                       if (clock_val > device_val) {
                         return;
                       }
                       if (clock_val + 1 != device_val) {
                         dropped_packets = device_val - clock_val;
                       }
                       clock_val = device_val;
                     }
                     request.request()->header.frame = timestamp / 8;
                     timestamp++;
                     Request::Queue(std::move(request), usb_);
                   });
    (*request).request()->header.frame = timestamp / 8;
    timestamp++;
    request->request()->direct = true;
    Request::Queue(std::move(*request), usb_);
  }
  sleep(kTestRuntime);
  test_results.received_isoch_packets = isoch_packets;
  test_results.isoch_packet_size = isoch_in_.w_max_packet_size;
  test_results.bulk_packet_size = bulk_out_.w_max_packet_size;
  test_results.got_correct_number_of_bytes_in_short_transfers = correct_byte_count;
  running = false;
  usb_.CancelAll(isoch_in_.b_endpoint_address);
  if (status != ZX_OK) {
    completer.ReplyError(status);
    return;
  }
  completer.ReplySuccess(test_results);
}

zx_status_t HciTest::Bind() { return DdkAdd("usb-hci-test"); }

void HciTest::EnumerationThread(ddk::InitTxn txn) {
  if (!usb_.is_valid()) {
    txn.Reply(ZX_ERR_NOT_SUPPORTED);
    return;
  }
  constexpr auto kNumEndpoints = 5;
  constexpr auto kInterfaceSubClass = 0;
  constexpr auto kInterfaceProtocol = 0;

  enum UsbInterface {
    InterruptIn = 0,
    IsochIn = 1,
    BulkOut = 3,
    BulkIn = 4,
  };

  std::optional<usb::InterfaceList> interfaces;
  usb::InterfaceList::Create(usb_, true, &interfaces);
  bool configured = false;
  for (auto iface : *interfaces) {
    if ((iface.descriptor()->b_num_endpoints == kNumEndpoints) &&
        (iface.descriptor()->b_interface_sub_class == kInterfaceSubClass) &&
        (iface.descriptor()->b_interface_protocol == kInterfaceProtocol)) {
      usb_.SetInterface(iface.descriptor()->b_interface_number,
                        iface.descriptor()->b_alternate_setting);
      size_t i = 0;
      for (auto ep : iface.GetEndpointList()) {
        switch (i) {
          case InterruptIn:
            // Interrupt endpoint
            irq_in_ = *ep.descriptor();
            irq_in_3_.b_descriptor_type = 0;
            if (ep.has_companion()) {
              irq_in_3_ = *ep.ss_companion().value();
              usb_.EnableEndpoint(ep.descriptor(), &irq_in_3_, true);
            } else {
              usb_.EnableEndpoint(ep.descriptor(), nullptr, true);
            }
            break;
          case IsochIn:
            isoch_in_ = *ep.descriptor();
            isoch_in_3_.b_descriptor_type = 0;
            if (ep.has_companion()) {
              isoch_in_3_ = *ep.ss_companion().value();
              usb_.EnableEndpoint(ep.descriptor(), &isoch_in_3_, true);
            } else {
              usb_.EnableEndpoint(ep.descriptor(), nullptr, true);
            }
            break;
          case BulkOut:
            bulk_out_ = *ep.descriptor();
            bulk_out_3_.b_descriptor_type = 0;
            if (ep.has_companion()) {
              bulk_out_3_ = *ep.ss_companion().value();
              usb_.EnableEndpoint(ep.descriptor(), &bulk_out_3_, true);
            } else {
              usb_.EnableEndpoint(ep.descriptor(), nullptr, true);
            }
            break;
          case BulkIn:
            configured = true;
            bulk_in_ = *ep.descriptor();
            bulk_in_3_.b_descriptor_type = 0;
            if (ep.has_companion()) {
              bulk_in_3_ = *ep.ss_companion().value();
              usb_.EnableEndpoint(ep.descriptor(), &bulk_in_3_, true);
            } else {
              usb_.EnableEndpoint(ep.descriptor(), nullptr, true);
            }
            break;
        }
        i++;
      }
    }
  }
  if (!configured) {
    txn.Reply(ZX_ERR_NOT_SUPPORTED);
    return;
  }
  txn.Reply(ZX_OK);
}

void HciTest::DdkInit(ddk::InitTxn txn) {
  enumeration_thread_.emplace([this, transaction = std::move(txn)]() mutable {
    EnumerationThread(std::move(transaction));
  });
}

zx_status_t HciTest::Create(void* ctx, zx_device_t* parent) {
  ddk::UsbProtocolClient usb(parent);
  auto dev = std::make_unique<HciTest>(parent, usb);

  zx_status_t status = dev->Bind();
  if (status == ZX_OK) {
    // Intentionally leak as it is now held by DevMgr.
    [[maybe_unused]] auto ptr = dev.release();
  }
  return status;
}

static constexpr zx_driver_ops_t kHciTestDriverOps = []() {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.bind = usb::HciTest::Create;
  return ops;
}();

}  // namespace usb

ZIRCON_DRIVER(usb_HciTest, usb::kHciTestDriverOps, "zircon", "0.1");
