#include "frc971/wpilib/dma.h"

#include <algorithm>
#include <cstring>
#include <type_traits>

#include "frc971/wpilib/ahal/AnalogInput.h"
#include "frc971/wpilib/ahal/DigitalSource.h"
#include "frc971/wpilib/ahal/Encoder.h"
#include "glog/logging.h"
#include "hal/HAL.h"

// Interface to the roboRIO FPGA's DMA features.

// Like tEncoder::tOutput with the bitfields reversed.
typedef union {
  struct {
    unsigned Direction : 1;
    signed Value : 31;
  };
  struct {
    unsigned value : 32;
  };
} t1Output;

static const int32_t kNumHeaders = 10;

static constexpr ssize_t kChannelSize[20] = {2, 2, 4, 4, 2, 2, 4, 4, 3, 3,
                                             2, 1, 4, 4, 4, 4, 4, 4, 4, 4};

enum DMAOffsetConstants {
  kEnable_AI0_Low = 0,
  kEnable_AI0_High = 1,
  kEnable_AIAveraged0_Low = 2,
  kEnable_AIAveraged0_High = 3,
  kEnable_AI1_Low = 4,
  kEnable_AI1_High = 5,
  kEnable_AIAveraged1_Low = 6,
  kEnable_AIAveraged1_High = 7,
  kEnable_Accumulator0 = 8,
  kEnable_Accumulator1 = 9,
  kEnable_DI = 10,
  kEnable_AnalogTriggers = 11,
  kEnable_Counters_Low = 12,
  kEnable_Counters_High = 13,
  kEnable_CounterTimers_Low = 14,
  kEnable_CounterTimers_High = 15,
  kEnable_Encoders_Low = 16,
  kEnable_Encoders_High = 17,
  kEnable_EncoderTimers_Low = 18,
  kEnable_EncoderTimers_High = 19,
};

DMA::DMA() {
  tRioStatusCode status = 0;
  tdma_config_ = tDMA::create(&status);
  tdma_config_->writeConfig_ExternalClock(false, &status);
  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
  if (status != 0) {
    return;
  }
  SetRate(1);
  SetPause(false);
}

DMA::~DMA() {
  tRioStatusCode status = 0;

  manager_->stop(&status);
  delete tdma_config_;
}

void DMA::SetPause(bool pause) {
  tRioStatusCode status = 0;
  tdma_config_->writeConfig_Pause(pause, &status);
  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}

void DMA::SetRate(uint32_t cycles) {
  if (cycles < 1) {
    cycles = 1;
  }
  tRioStatusCode status = 0;
  tdma_config_->writeRate(cycles, &status);
  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}

void DMA::Add(frc::Encoder *encoder) {
  tRioStatusCode status = 0;

  if (manager_) {
    wpi_setErrorWithContext(NiFpga_Status_InvalidParameter,
                            "DMA::Add() only works before DMA::Start()");
    return;
  }
  const int index = encoder->GetFPGAIndex();

  if (index < 4) {
    // TODO(austin): Encoder uses a Counter for 1x or 2x; quad for 4x...
    tdma_config_->writeConfig_Enable_Encoders_Low(true, &status);
  } else if (index < 8) {
    // TODO(austin): Encoder uses a Counter for 1x or 2x; quad for 4x...
    tdma_config_->writeConfig_Enable_Encoders_High(true, &status);
  } else {
    wpi_setErrorWithContext(
        NiFpga_Status_InvalidParameter,
        "FPGA encoder index is not in the 4 that get logged.");
    return;
  }

  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}

void DMA::Add(frc::DigitalSource * /*input*/) {
  tRioStatusCode status = 0;

  if (manager_) {
    wpi_setErrorWithContext(NiFpga_Status_InvalidParameter,
                            "DMA::Add() only works before DMA::Start()");
    return;
  }

  tdma_config_->writeConfig_Enable_DI(true, &status);
  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}

void DMA::Add(frc::AnalogInput *input) {
  tRioStatusCode status = 0;

  if (manager_) {
    wpi_setErrorWithContext(NiFpga_Status_InvalidParameter,
                            "DMA::Add() only works before DMA::Start()");
    return;
  }

  if (input->GetChannel() <= 3) {
    tdma_config_->writeConfig_Enable_AI0_Low(true, &status);
  } else {
    tdma_config_->writeConfig_Enable_AI0_High(true, &status);
  }
  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}

void DMA::SetExternalTrigger(frc::DigitalSource *input, bool rising,
                             bool falling) {
  CHECK(input);
  tRioStatusCode status = 0;

  if (manager_) {
    wpi_setErrorWithContext(
        NiFpga_Status_InvalidParameter,
        "DMA::SetExternalTrigger() only works before DMA::Start()");
    return;
  }

  auto index =
      ::std::find(trigger_channels_.begin(), trigger_channels_.end(), false);
  if (index == trigger_channels_.end()) {
    wpi_setErrorWithContext(NiFpga_Status_InvalidParameter,
                            "DMA: No channels left");
    return;
  }
  *index = true;

  const int channel_index = ::std::distance(trigger_channels_.begin(), index);

  const bool is_external_clock =
      tdma_config_->readConfig_ExternalClock(&status);
  if (status == 0) {
    if (!is_external_clock) {
      tdma_config_->writeConfig_ExternalClock(true, &status);
      wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
      if (status != 0) {
        return;
      }
    }
  } else {
    wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
    return;
  }

  nFPGA::nRoboRIO_FPGANamespace::tDMA::tExternalTriggers new_trigger;

  new_trigger.FallingEdge = falling;
  new_trigger.RisingEdge = rising;
  new_trigger.ExternalClockSource_AnalogTrigger = false;
  unsigned char module = 0;
  uint32_t channel = input->GetChannel();
  if (channel >= kNumHeaders) {
    module = 1;
    channel -= kNumHeaders;
  } else {
    module = 0;
  }

  new_trigger.ExternalClockSource_Module = module;
  new_trigger.ExternalClockSource_Channel = channel;

  // Configures the trigger to be external, not off the FPGA clock.
  tdma_config_->writeExternalTriggers(channel_index / 4, channel_index % 4,
                                      new_trigger, &status);
  if (status != 0) {
    wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
    return;
  }
}

DMA::ReadStatus DMA::Read(DMASample *sample, uint32_t timeout_ms,
                          size_t *remaining_out) {
  tRioStatusCode status = 0;
  size_t remainingBytes = 0;
  *remaining_out = 0;

  if (!manager_.get()) {
    wpi_setErrorWithContext(NiFpga_Status_InvalidParameter,
                            "DMA::Read() only works after DMA::Start()");
    return STATUS_ERROR;
  }

  sample->dma_ = this;
  manager_->read(sample->read_buffer_, capture_size_, timeout_ms,
                 &remainingBytes, &status);
  sample->CalculateTimestamp();

  // TODO(jerry): Do this only if status == 0?
  *remaining_out = remainingBytes / capture_size_;

  // TODO(austin): Check that *remainingBytes % capture_size_ == 0 and deal
  // with it if it isn't.  Probably meant that we overflowed?
  if (status == 0) {
    return STATUS_OK;
  } else if (status == NiFpga_Status_FifoTimeout) {
    return STATUS_TIMEOUT;
  } else {
    wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
    return STATUS_ERROR;
  }
}

const char *DMA::NameOfReadStatus(ReadStatus s) {
  switch (s) {
    case STATUS_OK:
      return "OK";
    case STATUS_TIMEOUT:
      return "TIMEOUT";
    case STATUS_ERROR:
      return "ERROR";
    default:
      return "(bad ReadStatus code)";
  }
}

void DMA::Start(size_t queue_depth) {
  tRioStatusCode status = 0;
  tconfig_ = tdma_config_->readConfig(&status);
  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
  if (status != 0) {
    return;
  }

  {
    size_t accum_size = 0;
#define SET_SIZE(bit)                      \
  if (tconfig_.bit) {                      \
    channel_offsets_[k##bit] = accum_size; \
    accum_size += kChannelSize[k##bit];    \
  } else {                                 \
    channel_offsets_[k##bit] = -1;         \
  }

    SET_SIZE(Enable_AI0_Low);
    SET_SIZE(Enable_AI0_High);
    SET_SIZE(Enable_AIAveraged0_Low);
    SET_SIZE(Enable_AIAveraged0_High);
    SET_SIZE(Enable_AI1_Low);
    SET_SIZE(Enable_AI1_High);
    SET_SIZE(Enable_AIAveraged1_Low);
    SET_SIZE(Enable_AIAveraged1_High);
    SET_SIZE(Enable_Accumulator0);
    SET_SIZE(Enable_Accumulator1);
    SET_SIZE(Enable_DI);
    SET_SIZE(Enable_AnalogTriggers);
    SET_SIZE(Enable_Counters_Low);
    SET_SIZE(Enable_Counters_High);
    SET_SIZE(Enable_CounterTimers_Low);
    SET_SIZE(Enable_CounterTimers_High);
    SET_SIZE(Enable_Encoders_Low);
    SET_SIZE(Enable_Encoders_High);
    SET_SIZE(Enable_EncoderTimers_Low);
    SET_SIZE(Enable_EncoderTimers_High);
#undef SET_SIZE
    capture_size_ = accum_size + 1;
  }

  manager_.reset(
      new nFPGA::tDMAManager(1, queue_depth * capture_size_, &status));

  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
  if (status != 0) {
    return;
  }
  // Start, stop, start to clear the buffer.
  manager_->start(&status);
  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
  if (status != 0) {
    return;
  }
  manager_->stop(&status);
  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
  if (status != 0) {
    return;
  }
  manager_->start(&status);
  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
  if (status != 0) {
    return;
  }
}

static_assert(::std::is_pod<DMASample>::value, "DMASample needs to be POD");

ssize_t DMASample::offset(int index) const {
  return dma_->channel_offsets_[index];
}

void DMASample::CalculateTimestamp() {
  uint32_t lower_sample = read_buffer_[dma_->capture_size_ - 1];
#if WPILIB2018
  int32_t status = 0;
  fpga_timestamp_ = HAL_ExpandFPGATime(lower_sample, &status);
  assert(status == 0);
#else
  fpga_timestamp_ = lower_sample;
#endif
}

uint64_t DMASample::GetTime() const { return fpga_timestamp_; }

double DMASample::GetTimestamp() const {
  return static_cast<double>(GetTime()) * 0.000001;
}

bool DMASample::Get(frc::DigitalSource *input) const {
  if (offset(kEnable_DI) == -1) {
    wpi_setStaticErrorWithContext(
        dma_, NiFpga_Status_ResourceNotFound,
        HAL_GetErrorMessage(NiFpga_Status_ResourceNotFound));
    return false;
  }
  const uint32_t channel = input->GetChannel();
  if (channel < kNumHeaders) {
    return (read_buffer_[offset(kEnable_DI)] >> channel) & 0x1;
  } else {
    return (read_buffer_[offset(kEnable_DI)] >> (channel + 6)) & 0x1;
  }
}

int32_t DMASample::GetRaw(frc::Encoder *input) const {
  int index = input->GetFPGAIndex();
  uint32_t dmaWord = 0;
  if (index < 4) {
    if (offset(kEnable_Encoders_Low) == -1) {
      wpi_setStaticErrorWithContext(
          dma_, NiFpga_Status_ResourceNotFound,
          HAL_GetErrorMessage(NiFpga_Status_ResourceNotFound));
      return -1;
    }
    dmaWord = read_buffer_[offset(kEnable_Encoders_Low) + index];
  } else if (index < 8) {
    if (offset(kEnable_Encoders_High) == -1) {
      wpi_setStaticErrorWithContext(
          dma_, NiFpga_Status_ResourceNotFound,
          HAL_GetErrorMessage(NiFpga_Status_ResourceNotFound));
      return -1;
    }
    dmaWord = read_buffer_[offset(kEnable_Encoders_High) + (index - 4)];
  } else {
    wpi_setStaticErrorWithContext(
        dma_, NiFpga_Status_ResourceNotFound,
        HAL_GetErrorMessage(NiFpga_Status_ResourceNotFound));
    return 0;
  }

  int32_t result = 0;

  // Extract the 31-bit signed tEncoder::tOutput Value using a struct with the
  // reverse packed field order of tOutput. This gets Value from the high
  // order 31 bits of output on little-endian ARM using gcc. This works
  // even though C/C++ doesn't guarantee bitfield order.
  t1Output output;

  output.value = dmaWord;
  result = output.Value;

  return result;
}

int32_t DMASample::Get(frc::Encoder *input) const {
  int32_t raw = GetRaw(input);

  return raw / input->GetEncodingScale();
}

uint16_t DMASample::GetValue(frc::AnalogInput *input) const {
  uint32_t channel = input->GetChannel();
  uint32_t dmaWord;
  if (channel < 4) {
    if (offset(kEnable_AI0_Low) == -1) {
      wpi_setStaticErrorWithContext(
          dma_, NiFpga_Status_ResourceNotFound,
          HAL_GetErrorMessage(NiFpga_Status_ResourceNotFound));
      return 0xffff;
    }
    dmaWord = read_buffer_[offset(kEnable_AI0_Low) + channel / 2];
  } else if (channel < 8) {
    if (offset(kEnable_AI0_High) == -1) {
      wpi_setStaticErrorWithContext(
          dma_, NiFpga_Status_ResourceNotFound,
          HAL_GetErrorMessage(NiFpga_Status_ResourceNotFound));
      return 0xffff;
    }
    dmaWord = read_buffer_[offset(kEnable_AI0_High) + (channel - 4) / 2];
  } else {
    wpi_setStaticErrorWithContext(
        dma_, NiFpga_Status_ResourceNotFound,
        HAL_GetErrorMessage(NiFpga_Status_ResourceNotFound));
    return 0xffff;
  }
  if (channel % 2) {
    return (dmaWord >> 16) & 0xffff;
  } else {
    return dmaWord & 0xffff;
  }
  return static_cast<int16_t>(dmaWord);
}

float DMASample::GetVoltage(frc::AnalogInput *input) const {
  uint16_t value = GetValue(input);
  if (value == 0xffff) return 0.0;
  uint32_t lsb_weight = input->GetLSBWeight();
  int32_t offset = input->GetOffset();
  float voltage = lsb_weight * 1.0e-9 * value - offset * 1.0e-9;
  return voltage;
}
