#ifndef MOTORS_USB_HID_H_
#define MOTORS_USB_HID_H_

#include <stdint.h>
#include <string.h>

#include <array>

#include "motors/usb/usb.h"
#include "motors/util.h"

namespace frc971::teensy {

// Implements an HID class device.
// TODO(Brian): Make this way more generic.
class HidFunction final : public UsbFunction {
 public:
  HidFunction(UsbDevice *device, int report_max_size)
      : UsbFunction(device), report_max_size_(report_max_size) {
    if (report_max_size_ > kMaxReportSize) {
      __builtin_trap();
    }
  }
  ~HidFunction() override = default;

  // Sets the report descriptor. Must be called at least once.
  //
  // May only be called during setup.
  void set_report_descriptor(const ::std::string &report_descriptor) {
    report_descriptor_ = report_descriptor;
  }

  void UpdateReport(const void *data, int length,
                    const DisableInterrupts &disable_interrupts) {
    memcpy(report_tx_buffer_to_fill(disable_interrupts), data, length);
  }

 private:
  // Choose 64 for now so it always fits into a single packet.
  static constexpr int kMaxReportSize = 64;

  uint8_t *report_tx_buffer_for(EvenOdd odd) {
    return report_tx_buffers_[EvenOddIndex(odd)].data();
  }
  uint8_t *report_tx_buffer_being_sent(const DisableInterrupts &) {
    return report_tx_buffer_for(BufferStateToEmpty(tx_state_));
  }
  uint8_t *report_tx_buffer_to_fill(const DisableInterrupts &) {
    return report_tx_buffer_for(BufferStateToFill(tx_state_));
  }

  int in_endpoint_max_size() const { return report_max_size_; }

  void Initialize() override;

  SetupResponse HandleEndpoint0SetupPacket(
      const UsbDevice::SetupPacket &setup_packet) override;
  SetupResponse HandleGetDescriptor(
      const UsbDevice::SetupPacket &setup_packet) override;

  void HandleInFinished(int endpoint, BdtEntry *bdt_entry,
                        EvenOdd odd) override;

  void HandleConfigured(int endpoint) override;
  void HandleReset() override {
    tx_state_ = EndpointBufferState::kBothEmptyEvenFirst;
    device()->SetBdtEntry(in_endpoint_, Direction::kTx, EvenOdd::kEven,
                          {0, nullptr});
    device()->SetBdtEntry(in_endpoint_, Direction::kTx, EvenOdd::kOdd,
                          {0, nullptr});
    {
      DisableInterrupts disable_interrupts;
      memset(report_tx_buffers_[0].data(), 0, kMaxReportSize);
      memset(report_tx_buffers_[1].data(), 0, kMaxReportSize);
    }
  }

  ::std::array<::std::array<uint8_t, kMaxReportSize>, 2> report_tx_buffers_;
  ::std::array<uint8_t, kMaxReportSize> get_report_response_buffer_;

  // This is only manipulated with interrupts disabled.
  EndpointBufferState tx_state_;
  Data01 next_tx_toggle_;

  // Our interface number.
  int interface_;

  // The IN endpoint we send reports on.
  int in_endpoint_;

  const int report_max_size_;

  ::std::string report_descriptor_;
  UsbDescriptorList hid_descriptor_list_;
};

}  // namespace frc971::teensy

#endif  // MOTORS_USB_HID_H_
