#include <Arduino.h>
#include <SPI.h>
#include <bitset>
#include <cstddef>
#include <stdint.h>

#include "gonk/adc.h"

#define PW_LOG_LEVEL PW_LOG_LEVEL_DEBUG
#define PW_LOG_MODULE_NAME "Adc"

#include "pw_bytes/bit.h"
#include "pw_bytes/endian.h"
#include "pw_bytes/span.h"
#include "pw_log/log.h"
#include "pw_result/result.h"
#include "pw_span/span.h"
#include "pw_status/status.h"

namespace gonk::adc {

namespace {

volatile uint8_t fpga_valid_pulse_ = 0;

void io_valid_rising_isr() {
  fpga_valid_pulse_ = 1;
  PW_LOG_DEBUG("IO Valid: HIGH");
}

void ClearValidPulse() { fpga_valid_pulse_ = 0; }

} // namespace

constexpr uint8_t INA229_CONFIG = 0x0;
constexpr uint8_t INA229_ADC_CONFIG = 0x1;
constexpr uint8_t INA229_SHUNT_CALIBRATION = 0x2;
constexpr uint8_t INA229_SHUNT_TEMP_COEFFICIENT = 0x3;
constexpr uint8_t INA229_VSHUNT = 0x4;
constexpr uint8_t INA229_VBUS = 0x5;
constexpr uint8_t INA229_DIETEMP = 0x6;
constexpr uint8_t INA229_CURRENT = 0x7;
constexpr uint8_t INA229_POWER = 0x8;
constexpr uint8_t INA229_ENERGY = 0x9;
constexpr uint8_t INA229_CHARGE = 0xA;
constexpr uint8_t INA229_DIAG_ALERT = 0xB;
constexpr uint8_t INA229_SHUNT_OVERVOLT_THRESHOLD = 0xC;
constexpr uint8_t INA229_SHUNT_UNDERVOLT_THRESHOLD = 0xD;
constexpr uint8_t INA229_BUS_OVERVOLT_THRESHOLD = 0xE;
constexpr uint8_t INA229_BUS_UNDERVOLT_THRESHOLD = 0xF;
constexpr uint8_t INA229_TEMP_LIMIT = 0x10;
constexpr uint8_t INA229_POWER_LIMIT = 0x11;

constexpr uint8_t INA229_MANUFACTURER_ID = 0x3e;
constexpr uint8_t INA229_DEVICE_ID = 0x3f;

constexpr uint8_t INA229RegisterByteSize[]{
    [INA229_CONFIG] = 2,
    [INA229_ADC_CONFIG] = 2,
    [INA229_SHUNT_CALIBRATION] = 2,
    [INA229_SHUNT_TEMP_COEFFICIENT] = 2,
    [INA229_VSHUNT] = 3,
    [INA229_VBUS] = 3,
    [INA229_DIETEMP] = 2,
    [INA229_CURRENT] = 3,
    [INA229_POWER] = 3,
    [INA229_ENERGY] = 5,
    [INA229_CHARGE] = 5,
    [INA229_DIAG_ALERT] = 2,
    [INA229_SHUNT_OVERVOLT_THRESHOLD] = 2,
    [INA229_SHUNT_UNDERVOLT_THRESHOLD] = 2,
    [INA229_BUS_OVERVOLT_THRESHOLD] = 2,
    [INA229_BUS_UNDERVOLT_THRESHOLD] = 2,
    [INA229_TEMP_LIMIT] = 2,
    [INA229_POWER_LIMIT] = 2,
};
constexpr pw::span<const uint8_t>
    kINA229RegisterByteSize(INA229RegisterByteSize);

Adc::Adc(SPIClass &fpga_spi, uint16_t fpga_spi_baudrate, uint16_t fpga_cs_pin,
         uint16_t fpga_mode_pin, uint16_t fpga_reset_pin,
         uint16_t fpga_valid_pin)
    : fpga_spi_(fpga_spi), fpga_reset_(fpga_reset_pin),
      fpga_mode_(fpga_mode_pin), fpga_valid_(fpga_valid_pin),
      fpga_cs_(fpga_cs_pin),
      spi_settings_(fpga_spi_baudrate, MSBFIRST, SPI_MODE1) {
  sample_read_index_ = 0;
  sample_read_time_.fill(0);
  vbus_measurements_.fill(0);
  vshunt_measurements_.fill(0);
}

void Adc::SetReadWriteMode() {
  // Reset FPGA logic
  digitalWrite(fpga_reset_, HIGH);
  delay(10);
  // Toggle mode to 0
  digitalWrite(fpga_mode_, LOW);
  delay(10);
  // Release reset
  digitalWrite(fpga_reset_, LOW);
  delay(10);
}

void Adc::SetContinuousReadMode() {
  // Reset FPGA logic
  digitalWrite(fpga_reset_, HIGH);
  delay(10);

  // Valid signal can go high from the FPGA side as soon as mode is set to 1.
  ClearValidPulse();

  // Toggle mode to 1
  digitalWrite(fpga_mode_, HIGH);
  delay(10);

  // Release reset
  digitalWrite(fpga_reset_, LOW);
  delay(10);
}

Status Adc::WaitForFpgaIOValid(uint32_t timeout_ms = 2000) {
  PW_LOG_DEBUG("FPGA Valid Signal: Waiting");

  uint32_t last_update = millis();
  uint32_t this_update = millis();
  bool done = false;
  int valid = 0;

  while (!done) {
    valid = digitalRead(fpga_valid_);
    if (valid == 1) {
      PW_LOG_DEBUG("FPGA Valid Signal: Result Ready");
      break;
    }

    this_update = millis();
    // If more than two seconds have passed something likely went wrong.
    if (this_update > last_update + timeout_ms) {
      PW_LOG_ERROR("FPGA Valid Signal: Timeout");
      last_update = this_update;
      return pw::Status::DeadlineExceeded();
    }
  }

  return pw::OkStatus();
}

Status Adc::WaitForFpgaIOValidPulse(uint32_t timeout_ms = 2000) {
  PW_LOG_DEBUG("FPGA Valid Pulse: Waiting");

  uint32_t last_update = millis();
  uint32_t this_update = millis();
  bool done = false;

  while (!done) {
    if (fpga_valid_pulse_ == 1) {
      PW_LOG_DEBUG("FPGA Valid Pulse: Detected");
      break;
    }

    this_update = millis();
    // If more than two seconds have passed something likely went wrong.
    if (this_update > last_update + timeout_ms) {
      PW_LOG_ERROR("FPGA Valid Pulse: Timeout");
      last_update = this_update;
      return pw::Status::DeadlineExceeded();
    }
  }

  return pw::OkStatus();
}

uint32_t Adc::ADCAddress(uint8_t adc_number, uint8_t adc_command,
                         uint8_t mode = 1) {
  // Address + Read/Write bit (24 bits)
  //
  // [23:18] - Dont Care bits
  // [17:7] - ADC Select. These 11 bits are used to select one or multiple ADCs
  //          for a write operation.
  //   [17] - ADC11 Select (ADC # from schematics)
  //   [16] - ADC10 Select
  //   ...
  //   [8] - ADC2 Select
  //   [7] - ADC1 Select
  //   NoTE: Select only one ADC for a read operation.
  // [6:1] - Register offset address for INA229.
  // [0] -  R/W bit. 1: READ, 0: WRITE

  const uint8_t adc_index = adc_number - 1;

  return (
      // ADC selection
      1 << (adc_index + 7)
      // ADC Register
      | ((adc_command & 0x3f) << 1)
      // 1=read, 0=write
      | mode);
}

uint32_t Adc::ADCAddressWrite(uint8_t adc_number, uint8_t adc_command) {
  // Address with mode=0 for a write.
  return ADCAddress(adc_number, adc_command, 0);
}

uint32_t Adc::ADCAddressWriteAll(uint8_t adc_command) {
  return (
      // Select all 11 ADCs
      0x7FF << 7
      // ADC Register
      | ((adc_command & 0x3f) << 1)
      // 1=read, 0=write
      | 0);
}

pw::Result<uint8_t> Adc::RegisterSize(uint8_t adc_register) {
  if (adc_register == INA229_MANUFACTURER_ID ||
      adc_register == INA229_DEVICE_ID) {
    return 2;
  }
  if (adc_register >= kINA229RegisterByteSize.size()) {
    PW_LOG_ERROR("Invalid register: %x", adc_register);
    return pw::Status::OutOfRange();
  }
  return INA229RegisterByteSize[adc_register];
}

void Adc::StartSpiTransaction() {
  digitalWrite(fpga_cs_, LOW);
  fpga_spi_.beginTransaction(spi_settings_);
}

void Adc::EndSpiTransaction() {
  digitalWrite(fpga_cs_, HIGH);
  fpga_spi_.endTransaction();
}

void Adc::WriteAddress(uint32_t adc_address) {
  uint8_t address[3];
  address[0] = (adc_address >> 16) & 0xff;
  address[1] = (adc_address >> 8) & 0xff;
  address[2] = adc_address & 0xff;

  PW_LOG_DEBUG("WriteAddress: %x %x %x", address[2], address[1], address[0]);

  fpga_spi_.transfer(address, 3);
}

pw::Result<pw::ConstByteSpan> Adc::ReadData(pw::ByteSpan read_buffer) {
  fpga_spi_.transfer(read_buffer.data(), read_buffer.size());

  return pw::ConstByteSpan(read_buffer);
}

Status Adc::WriteData(pw::ByteSpan write_buffer) {
  fpga_spi_.transfer(write_buffer.data(), write_buffer.size());

  return pw::OkStatus();
}

pw::Result<pw::ConstByteSpan> Adc::GetManufacturerID(uint8_t adc_number) {
  return GetRegister(adc_number, INA229_MANUFACTURER_ID);
}

pw::Result<pw::ConstByteSpan> Adc::GetRegister(uint8_t adc_number,
                                               uint8_t adc_register) {
  uint32_t adc_address = ADCAddress(adc_number, adc_register);

  StartSpiTransaction();
  WriteAddress(adc_address);

  Status wait_result = WaitForFpgaIOValid();
  if (!wait_result.ok()) {
    EndSpiTransaction();
    return wait_result;
  }

  pw::Result<uint8_t> register_size_result = RegisterSize(adc_register);
  if (!register_size_result.ok()) {
    return register_size_result.status();
  }

  std::array<std::byte, 5> read_buffer;
  pw::ByteSpan read_span =
      pw::ByteSpan(read_buffer.data(), register_size_result.value());

  const pw::Result<pw::ConstByteSpan> read_result = ReadData(read_span);
  if (!read_result.ok()) {
    return read_result.status();
  }

  EndSpiTransaction();

  return read_result.value();
}

pw::Result<pw::ConstByteSpan> Adc::GetThreeBytes() {
  std::array<std::byte, 3> read_buffer;
  pw::ByteSpan read_span = pw::ByteSpan(read_buffer);

  return ReadData(read_span);
}

Status Adc::UpdateContinuousMeasurements() {

  uint32_t start_time = micros();

  StartSpiTransaction();

  Status wait_result = WaitForFpgaIOValidPulse();
  if (!wait_result.ok()) {
    EndSpiTransaction();
    return wait_result;
  }

  for (int i = 0; i < kStreamingAdcCount; i++) {
    // Read VBUS
    std::array<std::byte, 3> vbus_read_buffer;
    const pw::Result<pw::ConstByteSpan> vbus_read_result =
        ReadData(pw::ByteSpan(vbus_read_buffer));
    if (!vbus_read_result.ok()) {
      PW_LOG_ERROR("vbus_read failed i=%d", i);
      return vbus_read_result.status();
    }
    int32_t vbus_value = VoltageMeasurement(vbus_read_result.value());
    vbus_measurements_[i] = vbus_value;
    PW_LOG_INFO("Continuous Read ADC #%02d: VBUS   = %02x %02x %02x = %d", i,
                vbus_read_result.value()[0], vbus_read_result.value()[1],
                vbus_read_result.value()[2], vbus_value);

    // Read VSHUNT
    std::array<std::byte, 3> vshunt_read_buffer;
    const pw::Result<pw::ConstByteSpan> vshunt_read_result =
        ReadData(pw::ByteSpan(vshunt_read_buffer));
    if (!vshunt_read_result.ok()) {
      PW_LOG_ERROR("vshunt_read failed i=%d", i);
      return vshunt_read_result.status();
    }
    int32_t vshunt_value = VoltageMeasurement(vshunt_read_result.value());
    vshunt_measurements_[i] = vshunt_value;
    PW_LOG_INFO("Continuous Read ADC #%02d: VSHUNT = %02x %02x %02x = %d", i,
                vshunt_read_result.value()[0], vshunt_read_result.value()[1],
                vshunt_read_result.value()[2], vshunt_value);
  }

  // All data has been read: clear the pulse signal variable.
  ClearValidPulse();

  EndSpiTransaction();

  uint32_t end_time = micros();
  sample_read_time_[sample_read_index_] = end_time - start_time;
  sample_read_index_ = (sample_read_index_ + 1) % sample_read_time_.size();

  return pw::OkStatus();
}

Status Adc::WriteRegister(uint8_t adc_number, uint8_t adc_register,
                          pw::ByteSpan write_buffer) {
  uint32_t adc_address = ADCAddressWrite(adc_number, adc_register);

  StartSpiTransaction();
  ClearValidPulse();
  WriteAddress(adc_address);
  WriteData(write_buffer);
  Status wait_result = WaitForFpgaIOValidPulse();
  EndSpiTransaction();

  return wait_result;
}

Status Adc::WriteRegisterAll(uint8_t adc_register, pw::ByteSpan write_buffer) {
  uint32_t adc_address = ADCAddressWriteAll(adc_register);

  StartSpiTransaction();
  ClearValidPulse();
  WriteAddress(adc_address);
  WriteData(write_buffer);
  Status wait_result = WaitForFpgaIOValidPulse();
  EndSpiTransaction();

  return wait_result;
}

pw::Result<pw::ConstByteSpan> Adc::GetADCConfiguration(uint8_t adc_number) {
  return GetRegister(adc_number, INA229_ADC_CONFIG);
}

Status Adc::SetADCConfiguration(uint8_t adc_number, pw::ByteSpan write_buffer) {
  return WriteRegister(adc_number, INA229_ADC_CONFIG, write_buffer);
}

pw::Result<pw::ConstByteSpan> Adc::GetShuntCalibration(uint8_t adc_number) {
  return GetRegister(adc_number, INA229_SHUNT_CALIBRATION);
}

pw::Result<int32_t> Adc::GetShuntVoltageMeasurement(uint8_t adc_number) {
  pw::Result<pw::ConstByteSpan> read_result =
      GetRegister(adc_number, INA229_VSHUNT);
  if (!read_result.ok()) {
    return read_result.status();
  }

  int32_t value = VoltageMeasurement(read_result.value());
  PW_LOG_INFO("ADC #%02d: VSHUNT = %02x %02x %02x = %d", adc_number,
              read_result.value()[0], read_result.value()[1],
              read_result.value()[2], value);

  return value;
}

pw::Result<int32_t> Adc::GetBusVoltageMeasurement(uint8_t adc_number) {
  pw::Result<pw::ConstByteSpan> read_result =
      GetRegister(adc_number, INA229_VBUS);
  if (!read_result.ok()) {
    return read_result.status();
  }

  int32_t value = VoltageMeasurement(read_result.value());
  PW_LOG_INFO("ADC #%02d: VBUS   = %02x %02x %02x = %d", adc_number,
              read_result.value()[0], read_result.value()[1],
              read_result.value()[2], value);

  return value;
}

int32_t Adc::VoltageMeasurement(pw::ConstByteSpan read_buffer) {
  // Convert bits 23 to 4 to a signed integer. Bits 3 to 0 are discarded.
  //
  // read_buffer[0] << 12  76543210<-----------|
  // read_buffer[1] << 4           76543210<---|
  // read_buffer[2] >> 4                   76543210--->
  // result                98765432109876543210|
  //
  return pw::bytes::SignExtend<20>((uint32_t)read_buffer[0] << 12 |
                                   (uint32_t)read_buffer[1] << 4 |
                                   (uint32_t)read_buffer[2] >> 4);
}

Status Adc::InitAdcs() {
  attachInterrupt(/*pin=*/fpga_valid_, /*callback=*/&io_valid_rising_isr,
                  /*mode=*/HIGH);

  SetReadWriteMode();

  PW_LOG_INFO("Init ADCs");

  // Set all ADC_CONFIG registers.
  std::array<std::byte, 2> adc_config = {
      // [15-12] MODE=0xB:   Continuous shunt and bus voltage
      // [8-6]   VBUSCT=0x0: 50us conversion time
      // [5-3]   VSHCT=0x0:  50us conversion time
      // [0-2]   AVG=0x0:    1 sample averaging count
      std::byte(0b10110000),
      std::byte(0b00000000),
  };
  WriteRegisterAll(INA229_ADC_CONFIG, adc_config);

  // Set all DIAG_ALERT registers
  std::array<std::byte, 2> diag_alert = {
      // CNVR=1: Enablne conversion ready flag
      std::byte(0b01000000),
      // MEMSTAT=1: Normal operation
      std::byte(0b00000000),
  };
  WriteRegisterAll(INA229_DIAG_ALERT, diag_alert);

  return pw::OkStatus();
}

Status Adc::CheckAllAdcs() {
  // Check all ADCs are reachable
  for (int adc_number = 1; adc_number <= kTotalAdcCount; adc_number++) {

    // Read and log the ADC_CONFIG register.
    const pw::Result<pw::ConstByteSpan> adc_config_result =
        GetADCConfiguration(adc_number);
    if (adc_config_result.ok()) {
      uint16_t adc_value = pw::bytes::ReadInOrder<uint16_t>(
          pw::endian::big, adc_config_result.value().data());
      PW_LOG_INFO("ADC #%02d: ADC Config = %x", adc_number, adc_value);
    }

    // Read and log the VSHUNT register.
    GetShuntVoltageMeasurement(adc_number);
    // Read and log the VBUS register.
    GetBusVoltageMeasurement(adc_number);
  }

  return pw::OkStatus();
}

} // namespace gonk::adc
