#ifndef MOTORS_USB_USB_H_
#define MOTORS_USB_USB_H_

#include <assert.h>
#include <string.h>

#include <memory>
#include <string>
#include <vector>

#include "aos/macros.h"
#include "motors/core/kinetis.h"
#include "motors/usb/constants.h"
#include "motors/util.h"

namespace frc971 {
namespace teensy {

// A sufficient memory barrier between writing some data and telling the USB
// hardware to read it or having the USB hardware say some data is readable and
// actually reading it.
static inline void dma_memory_barrier() { DmaMemoryBarrier(); }

// Aligned for faster access via memcpy etc.
//
// Also, the Freescale example stack forces aligned buffers to work around some
// hardware limitations which may or may not apply to our chips.
typedef void *DataPointer __attribute__((aligned(4)));

// An entry in the Buffer Descriptor Table.
struct BdtEntry {
  uint32_t buffer_descriptor;
  DataPointer address;
};

#define V_USB_BD_BC(value) \
  static_cast<uint32_t>(static_cast<uint32_t>(value) << 16)
#define G_USB_BD_BC(bd) (((bd) >> 16) & UINT32_C(0x3FF))
#define M_USB_BD_OWN UINT32_C(1 << 7)
#define M_USB_BD_DATA1 UINT32_C(1 << 6)
static_assert(static_cast<uint32_t>(Data01::kData1) == M_USB_BD_DATA1,
              "Wrong value");
#define M_USB_BD_KEEP UINT32_C(1 << 5)
#define M_USB_BD_NINC UINT32_C(1 << 4)
#define M_USB_BD_DTS UINT32_C(1 << 3)
#define M_USB_BD_STALL UINT32_C(1 << 2)
#define V_USB_BD_PID(value) \
  static_cast<uint32_t>(static_cast<uint32_t>(value) << 2)
#define G_USB_BD_PID(bd) static_cast<UsbPid>(((bd) >> 2) & UINT32_C(0xF))

#define G_USB_STAT_ENDP(stat) (((stat) >> 4) & UINT32_C(0xF))
#define M_USB_STAT_TX UINT32_C(1 << 3)
#define M_USB_STAT_ODD UINT32_C(1 << 2)

// The various types of descriptors defined in the standard for retrieval via
// GetDescriptor.
static constexpr uint8_t kUsbDescriptorTypeMin = 1;
static constexpr uint8_t kUsbDescriptorTypeMax = 11;
enum class UsbDescriptorType : uint8_t {
  kDevice = 1,
  kConfiguration = 2,
  kString = 3,
  kInterface = 4,
  kEndpoint = 5,
  kDeviceQualifier = 6,
  kOtherSpeedConfiguration = 7,
  kInterfacePower = 8,
  kOtg = 9,
  kDebug = 10,
  kInterfaceAssociation = 11,
};

// The class-specific descriptor types.
enum class UsbClassDescriptorType : uint8_t {
  kDevice = 0x21,
  kConfiguration = 0x22,
  kString = 0x23,
  kInterface = 0x24,
  kEndpoint = 0x25,

  kHidHid = 0x21,
  kHidReport = 0x22,
  kHidPhysical = 0x23,
};

// The names of the setup request types from the standard.
enum class SetupRequestType {
  kStandard = 0,
  kClass = 1,
  kVendor = 2,
  kReserved = 3,
};

// Set means device-to-host, clear means host-to-device.
#define M_SETUP_REQUEST_TYPE_IN UINT8_C(1 << 7)
#define G_SETUP_REQUEST_TYPE_TYPE(type) \
  static_cast<SetupRequestType>(((type) >> 5) & UINT8_C(3))
#define G_SETUP_REQUEST_TYPE_RECIPIENT(type) ((type) & UINT8_C(0x1F))
#define G_SETUP_REQUEST_INDEX_ENDPOINT(index) ((index) & UINT8_C(0x7F))

// The names of the standard recipients for setup requests.
namespace standard_setup_recipients {
constexpr int kDevice = 0;
constexpr int kInterface = 1;
constexpr int kEndpoint = 2;
constexpr int kOther = 3;
}  // namespace standard_setup_recipients

namespace microsoft_feature_descriptors {
constexpr int kExtendedCompatibilityId = 4;
constexpr int kExtendedProperties = 5;
}  // namespace microsoft_feature_descriptors

// The HID class specification says this. Can't find any mention in the main
// standard.
#define G_DESCRIPTOR_TYPE_TYPE(descriptor_type) \
  ((descriptor_type) >> 5 & UINT8_C(3))
namespace standard_descriptor_type_types {
constexpr int kStandard = 0;
constexpr int kClass = 1;
constexpr int kVendor = 2;
}  // namespace standard_descriptor_type_types

constexpr uint8_t vendor_specific_class() { return 0xFF; }

class UsbFunction;

// Allows building up a list of descriptors. This supports a much nicer API than
// the usual "hard-code a char[] with all the sizes and offsets at compile
// time". Space for each descriptor is reserved, and then it may be filled out
// from beginning to end at any time.
//
// An instance is the thing that the GetDescriptor operation sends to the host.
// This is not the concept that the core and class standards call "Foo
// Descriptor" etc; see Descriptor for that.
class UsbDescriptorList {
 public:
  // Represents a single descriptor. All of the contents must be written before
  // this object is destroyed.
  //
  // Create one via UsbDescriptorList::CreateDescriptor.
  class Descriptor {
   public:
    // All of the allocated space must be filled first.
    ~Descriptor() {
      if (descriptor_list_ == nullptr) {
        return;
      }
      // Verify we wrote all the bytes first.
      assert(next_index_ == end_index_);
      --descriptor_list_->open_descriptors_;
    }

    void AddUint16(uint16_t value) {
      AddByte(value & 0xFF);
      AddByte((value >> 8) & 0xFF);
    }

    void AddByte(uint8_t value) {
      assert(next_index_ < end_index_);
      data()[next_index_] = value;
      ++next_index_;
    }

    // Overwrites an already-written byte.
    void SetByte(int index, uint8_t value) {
      assert(index + start_index_ < end_index_);
      data()[index + start_index_] = value;
    }

   private:
    Descriptor(UsbDescriptorList *descriptor_list, int start_index,
               int end_index)
        : descriptor_list_(descriptor_list),
          start_index_(start_index),
          end_index_(end_index),
          next_index_(start_index_) {}

    char *data() const { return &descriptor_list_->data_[0]; }

    UsbDescriptorList *const descriptor_list_;
    const int start_index_, end_index_;
    int next_index_;

    friend class UsbDescriptorList;

    DISALLOW_COPY_AND_ASSIGN(Descriptor);
  };

  UsbDescriptorList() = default;
  ~UsbDescriptorList() = default;

  // Creates a new descriptor at the end of the list.
  // length is the number of bytes, including the length byte.
  // descriptor_type is the descriptor type, which is the second byte after the
  // length.
  ::std::unique_ptr<Descriptor> CreateDescriptor(
      uint8_t length, UsbDescriptorType descriptor_type) {
    return CreateDescriptor(length, static_cast<uint8_t>(descriptor_type));
  }

  ::std::unique_ptr<Descriptor> CreateDescriptor(
      uint8_t length, UsbClassDescriptorType descriptor_type) {
    assert(data_.size() > 0);
    return CreateDescriptor(length, static_cast<uint8_t>(descriptor_type));
  }

  void AddPremadeDescriptor(const uint8_t *data, int length) {
    const int start_index = data_.size();
    const int end_index = start_index + length;
    data_.resize(end_index);
    memcpy(&data_[start_index], data, length);
  }

  void AddPremadeDescriptor(const UsbDescriptorList &other_list) {
    other_list.CheckFinished();
    AddPremadeDescriptor(
        reinterpret_cast<const uint8_t *>(other_list.data_.data()),
        other_list.data_.size());
  }

  void CheckFinished() const { assert(open_descriptors_ == 0); }

  int CurrentSize() const { return data_.size(); }

  const char *GetData() const {
    CheckFinished();
    return data_.data();
  }

 private:
  ::std::unique_ptr<Descriptor> CreateDescriptor(uint8_t length,
                                                 uint8_t descriptor_type) {
    const int start_index = data_.size();
    const int end_index = start_index + length;
    data_.resize(end_index);
    ++open_descriptors_;
    auto r = ::std::unique_ptr<Descriptor>(
        new Descriptor(this, start_index, end_index));
    r->AddByte(length);           // bLength
    r->AddByte(descriptor_type);  // bDescriptorType
    return r;
  }

  int open_descriptors_ = 0;

  ::std::string data_;

  friend class UsbDevice;

  DISALLOW_COPY_AND_ASSIGN(UsbDescriptorList);
};

extern "C" void usb_isr(void);

// USB state events are managed by asking each function if it wants to handle
// them, sequentially. For the small number of functions which can be
// practically supported with the limited number of endpoints, this performs
// better than fancier things like hash maps.

// Manages one of the Teensy's USB peripherals as a USB slave device.
//
// This supports being a composite device with multiple functions.
//
// Attaching functions etc is called "setup", and must be completed before
// Initialize() is called.
//
// Detaching functions is called "teardown" and must happen after Shutdown().
// TODO(Brian): Implement Shutdown().
class UsbDevice final {
 public:
  // Represents the data that comes with a UsbPid::kSetup.
  // Note that the order etc is important because we memcpy into this.
  struct SetupPacket {
    uint8_t request_type;  // bmRequestType
    uint8_t request;       // bRequest
    uint16_t value;        // wValue
    uint16_t index;        // wIndex
    uint16_t length;       // wLength
  } __attribute__((aligned(4)));
  static_assert(sizeof(SetupPacket) == 8, "wrong size");

  enum class SetupResponse {
    // Indicates this function doesn't recognize the setup packet.
    kIgnored,

    // Indicates the endpoint should be stalled.
    //
    // Don't return this if the packet is for another function.
    kStall,

    // Indicates this setup packet was handled. Functions must avoid eating
    // packets intended for other functions.
    kHandled,
  };

  static constexpr int kEndpoint0MaxSize = 64;

  // The only language code we support.
  static constexpr uint16_t english_us_code() { return 0x0409; }

  UsbDevice(int index, uint16_t vendor_id, uint16_t product_id);
  ~UsbDevice();

  // Ends setup and starts being an actual USB device.
  void Initialize();

  // Adds a string to the table and returns its index.
  //
  // For simplicity, we only support strings with english_us_code().
  //
  // May only be called during setup.
  int AddString(const ::std::string &string) {
    assert(!is_set_up_);
    const int r = strings_.size();
    strings_.emplace_back(string.size() * 2 + 2, '\0');
    strings_.back()[0] = 2 + string.size() * 2;
    strings_.back()[1] = static_cast<uint8_t>(UsbDescriptorType::kString);
    for (size_t i = 0; i < string.size(); ++i) {
      strings_.back()[i * 2 + 2] = string[i];
    }
    return r;
  }

  // Sets the manufacturer string.
  //
  // May only be called during setup.
  void SetManufacturer(const ::std::string &string) {
    device_descriptor_->SetByte(14, AddString(string));  // iManufacturer
  }

  // Sets the product string.
  //
  // May only be called during setup.
  void SetProduct(const ::std::string &string) {
    device_descriptor_->SetByte(15, AddString(string));  // iProduct
  }

  // Sets the serial number string.
  //
  // May only be called during setup.
  void SetSerialNumber(const ::std::string &string) {
    device_descriptor_->SetByte(16, AddString(string));  // iSerialNumber
  }

  // Queues up an empty IN packet for endpoint 0. This is a common way to
  // respond to various kinds of configuration commands.
  //
  // This may only be called from the appropriate function callbacks.
  void SendEmptyEndpoint0Packet();

  // Queues some data to send on endpoint 0. This includes putting the initial
  // packets into the TX buffers.
  //
  // This may only be called from the appropriate function callbacks.
  void QueueEndpoint0Data(const char *data, int size);

  // Stalls an endpoint until it's cleared.
  //
  // This should only be called by or on behalf of the function which owns
  // endpoint.
  void StallEndpoint(int endpoint);

  // Configures an endpoint to send and/or receive, with or without DATA0/DATA1
  // handshaking. handshake should probably be true for everything except
  // isochronous endpoints.
  //
  // This should only be called by or on behalf of the function which owns
  // endpoint.
  void ConfigureEndpointFor(int endpoint, bool rx, bool tx, bool handshake);

  void SetBdtEntry(int endpoint, Direction direction, EvenOdd odd,
                   BdtEntry bdt_entry);

 private:
  // Clears all pending interrupts.
  void ClearInterrupts();

  // Deals with an interrupt that has occured.
  void HandleInterrupt();

  // Processes a token on endpoint 0.
  void HandleEndpoint0Token(uint8_t stat);

  // Processes a setup packet on endpoint 0.
  void HandleEndpoint0SetupPacket(const SetupPacket &setup_packet);

  // Sets endpoint 0 to return STALL tokens. We clear this condition upon
  // receiving the next SETUP token.
  void StallEndpoint0();

  // Places the first packet from {endpoint0_data_, endpoint0_data_left_} into
  // the TX buffers (if there is any data). This may only be called when the
  // next TX buffer is empty.
  bool BufferEndpoint0TxPacket();

  // Which USB peripheral this is.
  const int index_;

  // The string descriptors in order.
  ::std::vector<::std::string> strings_;

  // TODO(Brian): Refactor into something more generic, because I think this is
  // shared with all non-isochronous endpoints?
  Data01 endpoint0_tx_toggle_;
  EvenOdd endpoint0_tx_odd_;
  uint8_t endpoint0_receive_buffer_[2][kEndpoint0MaxSize]
      __attribute__((aligned(4)));

  // A temporary buffer for holding data to transmit on endpoint 0. Sometimes
  // this is used and sometimes the data is sent directly from some other
  // location (like for descriptors).
  char endpoint0_transmit_buffer_[kEndpoint0MaxSize];

  // The data we're waiting to send from endpoint 0. The data must remain
  // constant until this transmission is done.
  //
  // When overwriting this, we ignore if it's already non-nullptr. The host is
  // supposed to read all of the data before asking for more. If it doesn't do
  // that, it will just get garbage data because it's unclear what it expects.
  //
  // Do note that endpoint0_data_ != nullptr && endpoint0_data_left_ == 0 is an
  // important state. This means we're going to return a 0-length packet the
  // next time the host asks. However, depending on the length it asked for,
  // that might never happen.
  const char *endpoint0_data_ = nullptr;
  int endpoint0_data_left_ = 0;

  // If non-0, the new address we're going to start using once the status stage
  // of the current setup request is finished.
  uint16_t new_address_ = 0;

  UsbDescriptorList device_descriptor_list_;
  UsbDescriptorList config_descriptor_list_;

  ::std::unique_ptr<UsbDescriptorList::Descriptor> device_descriptor_,
      config_descriptor_;

  int configuration_ = 0;

  bool is_set_up_ = false;

  // The function which owns each endpoint.
  ::std::vector<UsbFunction *> endpoint_mapping_;
  // The function which owns each interface.
  ::std::vector<UsbFunction *> interface_mapping_;
  // All of the functions (without duplicates).
  ::std::vector<UsbFunction *> functions_;

  // Filled out during Initialize().
  ::std::string microsoft_extended_id_descriptor_;

  friend void usb_isr(void);
  friend class UsbFunction;
};

// Represents a USB function. This consists of a set of descriptors and
// interfaces.
//
// Each instance is a single function, so there can be multiple instances of the
// same subclass in the same devices (ie two serial ports).
class UsbFunction {
 public:
  UsbFunction(UsbDevice *device) : device_(device) {
    device_->functions_.push_back(this);
  }
  virtual ~UsbFunction() = default;

 protected:
  using SetupResponse = UsbDevice::SetupResponse;

  static constexpr uint8_t iad_descriptor_length() { return 8; }
  static constexpr uint8_t interface_descriptor_length() { return 9; }
  static constexpr uint8_t endpoint_descriptor_length() { return 7; }

  static constexpr uint8_t m_endpoint_address_in() { return 1 << 7; }
  static constexpr uint8_t m_endpoint_attributes_control() { return 0x00; }
  static constexpr uint8_t m_endpoint_attributes_isochronous() { return 0x01; }
  static constexpr uint8_t m_endpoint_attributes_bulk() { return 0x02; }
  static constexpr uint8_t m_endpoint_attributes_interrupt() { return 0x03; }

  // Adds a new endpoint and returns its index.
  //
  // Note that at least one descriptor for this newly created endpoint must be
  // added via CreateConfigDescriptor.
  //
  // TODO(Brian): Does this hardware actually only support a single direction
  // per endpoint number, or can it get a total of 30 endpoints max?
  //
  // May only be called during setup.
  int AddEndpoint();

  // Adds a new interface and returns its index.
  //
  // You'll probably want to put this new interface in at least one descriptor
  // added via CreateConfigDescriptor.
  //
  // May only be called during setup.
  int AddInterface();

  // Adds a new descriptor in the configuration descriptor list. See
  // UsbDescriptorList::CreateDescriptor for details.
  //
  // Note that the order of calls to this is highly significant. In general,
  // this should only be called from Initialize().
  //
  // May only be called during setup.
  template <typename T>
  ::std::unique_ptr<UsbDescriptorList::Descriptor> CreateDescriptor(
      uint8_t length, T descriptor_type) {
    return device_->config_descriptor_list_.CreateDescriptor(length,
                                                             descriptor_type);
  }
  void AddPremadeDescriptor(const uint8_t *data, int length) {
    device_->config_descriptor_list_.AddPremadeDescriptor(data, length);
  }
  void AddPremadeDescriptor(const UsbDescriptorList &other_list) {
    device_->config_descriptor_list_.AddPremadeDescriptor(other_list);
  }

  UsbDevice *device() const { return device_; }

  void CreateIadDescriptor(int first_interface, int interface_count,
                           int function_class, int function_subclass,
                           int function_protocol,
                           const ::std::string &function);

  // Sets the interface GUIDs for this function. Each GUID (one per interface?)
  // should be followed by a NUL.
  //
  // If this is never called, no GUID extended property will be reported.
  //
  // This is needed to pass to Windows so WinUSB will be happy. Generate them at
  // https://www.guidgenerator.com/online-guid-generator.aspx (Uppcase, Braces,
  // and Hyphens).
  //
  // May only be called during setup.
  void SetMicrosoftDeviceInterfaceGuids(const ::std::string &guids);

 private:
  virtual void Initialize() = 0;

  virtual SetupResponse HandleEndpoint0SetupPacket(
      const UsbDevice::SetupPacket & /*setup_packet*/) {
    return SetupResponse::kIgnored;
  }

  virtual SetupResponse HandleEndpoint0OutPacket(void * /*data*/,
                                                 int /*data_length*/) {
    return SetupResponse::kIgnored;
  }

  virtual SetupResponse HandleGetDescriptor(
      const UsbDevice::SetupPacket & /*setup_packet*/) {
    return SetupResponse::kIgnored;
  }

  // Returns the concatenated compatible ID and subcompatible ID.
  virtual ::std::string MicrosoftExtendedCompatibleId() {
    // Default to both of them being "unused".
    return ::std::string(16, '\0');
  }

  virtual void HandleOutFinished(int /*endpoint*/, BdtEntry * /*bdt_entry*/) {}
  virtual void HandleInFinished(int /*endpoint*/, BdtEntry * /*bdt_entry*/,
                                EvenOdd /*odd*/) {}

  // Called when a given interface is configured (aka "experiences a
  // configuration event"). This means all rx and tx buffers have been cleared
  // and should be filled as appropriate, starting from data0. Also,
  // ConfigureEndpointFor should be called with the appropriate arguments.
  virtual void HandleConfigured(int endpoint) = 0;

  // Should reset everything to use the even buffers next.
  virtual void HandleReset() = 0;

  int first_interface_ = -1;

  // Filled out during Initialize().
  ::std::string microsoft_extended_property_descriptor_;

  UsbDevice *const device_;

  friend class UsbDevice;
};

}  // namespace teensy
}  // namespace frc971

#endif  // MOTORS_USB_USB_H_
