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

#ifndef SRC_DEVICES_USB_LIB_USB_INCLUDE_USB_REQUEST_FIDL_H_
#define SRC_DEVICES_USB_LIB_USB_INCLUDE_USB_REQUEST_FIDL_H_

#include <fidl/fuchsia.hardware.usb.request/cpp/fidl.h>
#include <lib/zx/bti.h>
#include <lib/zx/vmar.h>

#include <queue>

#include <fbl/auto_lock.h>
#include <fbl/mutex.h>

#include "src/devices/usb/lib/usb/include/usb/usb-request.h"

namespace usb {

// EndpointType: One of 4 endpoint types as defined by USB.
enum EndpointType : uint8_t {
  UNKNOWN,

  CONTROL,
  BULK,
  ISOCHRONOUS,
  INTERRUPT,
};

// MappedVmo is a container that keeps track of the virtual address and size of the VMO mapped.
struct MappedVmo {
  // addr: virtual address.
  zx_vaddr_t addr;
  // size: size of VMO that was mapped to this virtual address.
  size_t size;
};

// FidlRequest is a wrapper around a fuchsia_hardware_usb_request::Request implementing common
// functionality. Especially, FidlRequest keeps track of VMOs that were pinned upon PhysMap() and
// unpins them upon destruction.
class FidlRequest {
 public:
  using get_mapped_func_t = std::function<zx::result<std::optional<usb::MappedVmo>>(
      const fuchsia_hardware_usb_request::Buffer& buffer)>;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FidlRequest);

  FidlRequest() = default;
  explicit FidlRequest(EndpointType ep_type) {
    switch (ep_type) {
      case CONTROL:
        set_control();
        break;
      case BULK:
        set_bulk();
        break;
      case ISOCHRONOUS:
        set_isochronous();
        break;
      case INTERRUPT:
        set_interrupt();
        break;
      default:
        ZX_ASSERT(false);
    };
  }
  explicit FidlRequest(fuchsia_hardware_usb_request::Request request)
      : request_(std::move(request)) {}
  FidlRequest(FidlRequest&& request) = default;
  ~FidlRequest() { Unpin(); }

  FidlRequest& set_control(fuchsia_hardware_usb_descriptor::UsbSetup setup = {}) {
    request_.information(fuchsia_hardware_usb_request::RequestInfo::WithControl(
        fuchsia_hardware_usb_request::ControlRequestInfo().setup(std::move(setup))));
    return *this;
  }
  FidlRequest& set_bulk() {
    request_.information(fuchsia_hardware_usb_request::RequestInfo::WithBulk(
        fuchsia_hardware_usb_request::BulkRequestInfo()));
    return *this;
  }
  FidlRequest& set_isochronous(uint64_t frame_id = 0) {
    request_.information(fuchsia_hardware_usb_request::RequestInfo::WithIsochronous(
        fuchsia_hardware_usb_request::IsochronousRequestInfo().frame_id(frame_id)));
    return *this;
  }
  FidlRequest& set_interrupt() {
    request_.information(fuchsia_hardware_usb_request::RequestInfo::WithInterrupt(
        fuchsia_hardware_usb_request::InterruptRequestInfo()));
    return *this;
  }

  FidlRequest& add_vmo_id(uint64_t vmo_id, size_t size = 0, size_t offset = 0) {
    if (!request_.data().has_value()) {
      request_.data().emplace();
    }

    request_.data()
        ->emplace_back()
        .buffer(fuchsia_hardware_usb_request::Buffer::WithVmoId(vmo_id))
        .offset(offset)
        .size(size);
    return *this;
  }
  FidlRequest& add_data(std::vector<uint8_t> data = {}, size_t size = 0, size_t offset = 0) {
    if (!request_.data().has_value()) {
      request_.data().emplace();
    }

    request_.data()
        ->emplace_back()
        .buffer(fuchsia_hardware_usb_request::Buffer::WithData(std::move(data)))
        .offset(offset)
        .size(size);
    return *this;
  }
  FidlRequest& clear_buffers() {
    for (auto& d : *request_.data()) {
      d.offset(0);
      d.size(0);
      if (d.buffer()->Which() == fuchsia_hardware_usb_request::Buffer::Tag::kData) {
        d.buffer()->data()->clear();
      }
    }
    return *this;
  }
  FidlRequest& reset_buffers(get_mapped_func_t GetMapped) {
    for (auto& d : *request_.data()) {
      d.offset(0);
      switch (d.buffer()->Which()) {
        case fuchsia_hardware_usb_request::Buffer::Tag::kVmoId: {
          auto mapped = GetMapped(*d.buffer());
          ZX_ASSERT(mapped.is_ok());
          d.size(mapped->size);
        } break;
        case fuchsia_hardware_usb_request::Buffer::Tag::kData:
          d.size(fuchsia_hardware_usb_request::kMaxTransferSize);
          break;
        default:
          break;
      }
    }
    return *this;
  }

  // CopyTo: tries to copy `size` bytes from `buffer` to contiguous `request` buffers from
  // `offset`. Returns the number of bytes copied for each buffer.
  std::vector<size_t> CopyTo(size_t offset, const void* buffer, size_t size,
                             get_mapped_func_t GetMapped) {
    const uint8_t* start = static_cast<const uint8_t*>(buffer);
    size_t todo = size;
    size_t cur_offset = offset;
    std::vector<size_t> cp_sizes(request_.data()->size(), 0);
    int32_t i = -1;
    for (auto& d : *request_.data()) {
      // Accumulator accounting done at head of loop due to multiple exit logic paths.
      i++;
      auto mapped = GetMapped(*d.buffer());
      if (mapped.is_error()) {
        return cp_sizes;
      }

      uint8_t* addr;
      size_t buffer_size;
      if (!mapped.value()) {
        // Buffer is fuchsia_hardware_usb_request::Buffer::Tag::kData
        buffer_size =
            std::min(todo, static_cast<size_t>(fuchsia_hardware_usb_request::kMaxTransferSize));
        d.buffer()->data()->resize(buffer_size);
        addr = d.buffer()->data()->data();
      } else {
        buffer_size = mapped->size;
        addr = reinterpret_cast<uint8_t*>(mapped->addr);
      }

      if (cur_offset >= buffer_size) {
        cur_offset -= buffer_size;
        continue;
      }

      size_t cp_size = std::min(todo, buffer_size - cur_offset);
      memcpy(addr + cur_offset, start, cp_size);
      cur_offset = 0;
      start += cp_size;
      todo -= cp_size;
      cp_sizes[i] = cp_size;

      if (todo == 0) {
        // Break out early.
        break;
      }
    }

    return cp_sizes;
  }

  // CopyFrom: tries to copy `size` bytes from `request` (starting from `offset`) to `buffer`.
  // Returns the number of bytes copied for each buffer.
  std::vector<size_t> CopyFrom(size_t offset, void* buffer, size_t size,
                               get_mapped_func_t GetMapped) {
    uint8_t* start = static_cast<uint8_t*>(buffer);
    size_t todo = size;
    size_t cur_offset = offset;
    std::vector<size_t> cp_sizes(request_.data()->size(), 0);
    int32_t i = -1;
    for (const auto& d : *request_.data()) {
      // Accumulator accounting done at head of loop due to multiple exit logic paths.
      i++;
      if (cur_offset >= *d.size()) {
        cur_offset -= *d.size();
        continue;
      }

      auto mapped = GetMapped(*d.buffer());
      if (mapped.is_error()) {
        return cp_sizes;
      }

      zx_vaddr_t addr;
      if (!mapped.value()) {
        // Buffer is fuchsia_hardware_usb_request::Buffer::Tag::kData.
        addr = reinterpret_cast<zx_vaddr_t>(d.buffer()->data()->data());
      } else {
        addr = mapped->addr;
      }

      size_t cp_size = std::min(todo, *d.size() - cur_offset);
      memcpy(start, reinterpret_cast<uint8_t*>(addr) + cur_offset, cp_size);
      cur_offset = 0;
      start += cp_size;
      todo -= cp_size;
      cp_sizes[i] = cp_size;

      if (todo == 0) {
        // Break out early.
        break;
      }
    }

    return cp_sizes;
  }

  // About CacheFlush and CacheFlushInvalidate: CacheFlush or CacheFlush invalidate MUST always be
  // called after data is written to the VMO and before the data is processed on schedule (see
  // comment in endpoint.fidl on `RequestQueue`).
  // CacheFlush should be called for operations where data is to be written out, but not read in
  // and CacheFlushInvalidate should be called for operations where data needs to be read in.
  // CacheFlush and CacheFlushInvalidate flush and invalidate cache for all buffer regions of a
  // request.
  zx_status_t CacheFlushInvalidate(get_mapped_func_t GetMapped) {
    zx_status_t ret_status = ZX_OK;
    for (const auto& d : *request_.data()) {
      auto status = CacheHelper(d, ZX_CACHE_FLUSH_DATA | ZX_CACHE_FLUSH_INVALIDATE, GetMapped);
      if (status != ZX_OK) {
        // Return the latest failed status value, but keep trying to flush other buffer regions
        ret_status = status;
      }
    }
    return ret_status;
  }

  zx_status_t CacheFlush(get_mapped_func_t GetMapped) {
    zx_status_t ret_status = ZX_OK;
    for (const auto& d : *request_.data()) {
      auto status = CacheHelper(d, ZX_CACHE_FLUSH_DATA, GetMapped);
      if (status != ZX_OK) {
        // Return the latest failed status value, but keep trying to flush other buffer regions
        ret_status = status;
      }
    }
    return ret_status;
  }

  // CacheHelper flushes and invaldiates cache for specified buffer region.
  zx_status_t CacheHelper(const fuchsia_hardware_usb_request::BufferRegion& buffer,
                          uint32_t options, get_mapped_func_t GetMapped) {
    auto mapped = GetMapped(*buffer.buffer());
    if (mapped.is_error()) {
      return mapped.error_value();
    }
    if (!mapped.value()) {
      return ZX_OK;
    }

    auto status = zx_cache_flush(reinterpret_cast<void*>(mapped->addr), *buffer.size(), options);
    if (status != ZX_OK) {
      return status;
    }
    return ZX_OK;
  }

  // Pins VMOs if needed. For
  //  - fuchsia_hardware_usb_request::Buffer::Tag::kVmoId -- Uses preregistered VMO. Does nothing.
  //  - fuchsia_hardware_usb_request::Buffer::Tag::kVmo   -- Pins VMO.
  //  - fuchsia_hardware_usb_request::Buffer::Tag::kData  -- Creates, maps, pins, VMO. Copies data
  //                                                         to VMO. (Unmapped and unpinned on
  //                                                         Unpin()).
  zx_status_t PhysMap(const zx::bti& bti) {
    int64_t idx = -1;
    for (auto& d : *request_.data()) {
      idx++;
      zx_handle_t vmo_handle = ZX_HANDLE_INVALID;
      void* mapped;
      switch (d.buffer()->Which()) {
        case fuchsia_hardware_usb_request::Buffer::Tag::kVmoId:
          // Pre-registered and already pinned. Does not need to be pinned again.
          continue;
        case fuchsia_hardware_usb_request::Buffer::Tag::kData: {
          // The price to pay for using fuchsia_hardware_usb_request::Buffer::Tag::kData instead
          // of VMOs is that a VMO needs to be created, mapped, pinned, data needs to be copied
          // to/from data buffer in both directions regardless of endpoint direction, cache needs
          // to be flushed, vmo then unpinned, and then unmapped.
          zx::vmo vmo;
          auto status = zx::vmo::create(*d.size(), 0, &vmo);
          if (status != ZX_OK) {
            return status;
          }

          status =
              zx::vmar::root_self()->map(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, vmo, *d.offset(),
                                         *d.size(), reinterpret_cast<uintptr_t*>(&mapped));
          if (status != ZX_OK) {
            return status;
          }

          memcpy(mapped, d.buffer()->data()->data(), *d.size());
          zx_cache_flush(&mapped, *d.size(), ZX_CACHE_FLUSH_DATA | ZX_CACHE_FLUSH_INVALIDATE);
          vmo_handle = vmo.release();
        } break;
        default:
          return ZX_ERR_NOT_SUPPORTED;
      }

      // Pin VMO.
      usb_request_t req = {
          .vmo_handle = vmo_handle,
          .size = *d.size(),
          .offset = *d.offset(),
          .pmt = ZX_HANDLE_INVALID,
          .phys_list = nullptr,
          .phys_count = 0,
      };
      // Abusing usb_request_physmap
      auto status = usb_request_physmap(&req, bti.get());
      if (status != ZX_OK) {
        return status;
      }
      pinned_vmos_[idx] = {req.pmt,
                           req.phys_list,
                           req.phys_count,
                           {reinterpret_cast<zx_vaddr_t>(mapped), *d.size()}};
    }

    return ZX_OK;
  }

  // Unpins VMOs pinned by PhysMap.
  zx_status_t Unpin() {
    auto pinned_vmos = std::move(pinned_vmos_);
    for (const auto& [idx, pinned] : pinned_vmos) {
      if ((*request_.data())[idx].buffer()->Which() ==
          fuchsia_hardware_usb_request::Buffer::Tag::kData) {
        memcpy((*request_.data())[idx].buffer()->data()->data(),
               reinterpret_cast<void*>(pinned.mapped.addr),
               std::min(*(*request_.data())[idx].size(), pinned.mapped.size));

        auto status = zx::vmar::root_self()->unmap(reinterpret_cast<uintptr_t>(pinned.mapped.addr),
                                                   pinned.mapped.size);
        ZX_DEBUG_ASSERT(status == ZX_OK);
      }

      auto status = zx_pmt_unpin(pinned.pmt);
      ZX_DEBUG_ASSERT(status == ZX_OK);
      free(pinned.phys_list);
    }
    return ZX_OK;
  }

  // Gets ddk::PhysIter for the buffer at request.data()->at(idx)
  ddk::PhysIter phys_iter(size_t idx, size_t max_length) const {
    ZX_ASSERT(request_.data()->at(idx).size());
    ZX_ASSERT(pinned_vmos_.find(idx) != pinned_vmos_.end());
    auto length = *request_.data()->at(idx).size();
    auto offset = *request_.data()->at(idx).offset();
    static_assert(sizeof(phys_iter_sg_entry_t) == sizeof(sg_entry_t) &&
                  offsetof(phys_iter_sg_entry_t, length) == offsetof(sg_entry_t, length) &&
                  offsetof(phys_iter_sg_entry_t, offset) == offsetof(sg_entry_t, offset));
    phys_iter_buffer_t buf = {.phys = pinned_vmos_.at(idx).phys_list,
                              .phys_count = pinned_vmos_.at(idx).phys_count,
                              .length = length,
                              .vmo_offset = offset,
                              .sg_list = nullptr,
                              .sg_count = 0};
    return ddk::PhysIter(buf, max_length);
  }

  fuchsia_hardware_usb_request::Request* operator->() { return &request_; }
  const fuchsia_hardware_usb_request::Request* operator->() const { return &request_; }
  const fuchsia_hardware_usb_request::Request& request() const { return request_; }
  // Ensures any removal of `request` is intentional and `Unpin` is called.
  fuchsia_hardware_usb_request::Request take_request() {
    ZX_DEBUG_ASSERT(Unpin() == ZX_OK);
    return std::move(request_);
  }
  // Returns the total length of all data in the request. Saves to a variable for future use.
  size_t length() {
    if (!_length) {
      size_t len = 0;
      for (const auto& d : *request_.data()) {
        ZX_ASSERT(d.size());
        len += *d.size();
      }
      *_length = len;
    }
    return *_length;
  }

 private:
  // request_: FIDL request object.
  fuchsia_hardware_usb_request::Request request_;

  struct pinned_vmo_t {
    zx_handle_t pmt;
    uint64_t* phys_list;
    size_t phys_count;
    // mapped: only used for fuchsia_hardware_usb_request::Buffer::Tag::kData.
    MappedVmo mapped;
  };
  // pinned_vmos_: VMOs that were pinned by this request when PhysMap() was called. Will be
  // unpinned by when this request is destructed or when Unpin() is called. Indexed in the same
  // order as request_.data(), where only buffers that are
  // fuchsia_hardware_usb_request::Buffer::Tag::kVmoId are left empty.
  std::map<size_t, pinned_vmo_t> pinned_vmos_ = {};

  // _length: Total length saved so calculation doesn't have to be done multiple times.
  std::optional<size_t> _length = std::nullopt;
};

// FidlRequestPool: pool of FidlRequests.
class FidlRequestPool {
 public:
  // When destructing, all of our requests should be sitting in the free list.
  ~FidlRequestPool() { ZX_DEBUG_ASSERT(free_reqs_.size() == size_); }

  // Add: called when adding a new request to the pool.
  void Add(usb::FidlRequest&& request) {
    size_++;
    Put(std::move(request));
  }

  // Remove: called when removing a request from the pool.
  std::optional<usb::FidlRequest> Remove() {
    auto req = Get();
    if (req.has_value()) {
      size_--;
    }
    return req;
  }

  std::optional<usb::FidlRequest> Get() {
    fbl::AutoLock _(&mutex_);
    if (free_reqs_.empty()) {
      return std::nullopt;
    }

    auto req = std::move(free_reqs_.front());
    free_reqs_.pop();
    return std::move(req);
  }

  // Put: called when a request (originally obtained from `get`) is returned to the pool.
  void Put(usb::FidlRequest&& request) {
    fbl::AutoLock _(&mutex_);
    free_reqs_.emplace(std::move(request));
    ZX_DEBUG_ASSERT(free_reqs_.size() <= size_);
  }

  bool Full() {
    fbl::AutoLock _(&mutex_);
    return free_reqs_.size() == size_;
  }
  bool Empty() {
    fbl::AutoLock _(&mutex_);
    return free_reqs_.empty();
  }

 private:
  fbl::Mutex mutex_;
  std::queue<usb::FidlRequest> free_reqs_ __TA_GUARDED(mutex_);

  std::atomic_uint32_t size_ = 0;
};

}  // namespace usb

#endif  // SRC_DEVICES_USB_LIB_USB_INCLUDE_USB_REQUEST_FIDL_H_
