#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 {
namespace 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 teensy
}  // namespace frc971

#endif  // MOTORS_USB_HID_H_
