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

#include "gonk/spi_flash.h"

#define PW_LOG_LEVEL PW_LOG_LEVEL_DEBUG
#define PW_LOG_MODULE_NAME "SpiFlash"

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

namespace gonk::spi_flash {

SpiFlash::SpiFlash(uint16_t flash_cs, int baudrate)
    : flash_cs_(flash_cs), spi_settings_(baudrate, MSBFIRST, SPI_MODE0) {}

Status SpiFlash::WriteEnable() {
  SPI.beginTransaction(spi_settings_);
  digitalWrite(flash_cs_, LOW);
  SPI.transfer(0x06);
  digitalWrite(flash_cs_, HIGH);
  SPI.endTransaction();

  return pw::OkStatus();
}

Status SpiFlash::WriteDisable() {
  SPI.beginTransaction(spi_settings_);
  digitalWrite(flash_cs_, LOW);
  SPI.transfer(0x04);
  digitalWrite(flash_cs_, HIGH);
  SPI.endTransaction();

  return pw::OkStatus();
}

std::bitset<8> SpiFlash::StatusRegister() {
  uint8_t status_register[2] = {
      0x05, // Read Status Register
      0,    // Result value
  };

  SPI.beginTransaction(spi_settings_);
  digitalWrite(flash_cs_, LOW);
  SPI.transfer(status_register, 2);
  digitalWrite(flash_cs_, HIGH);
  SPI.endTransaction();

  return (std::bitset<8>)status_register[1];
}

bool SpiFlash::IsBusy() {
  // 1 in the first bit of the status register indicates the device is busy.
  return StatusRegister()[0];
}

bool SpiFlash::WritingIsEnabled() {
  // 1 in the second bit of the status register indicates the device is busy.
  return StatusRegister()[1];
}

Status SpiFlash::Erase() {
  if (!WritingIsEnabled()) {
    return pw::Status::FailedPrecondition();
  }

  PW_LOG_DEBUG("Start Flash Erase");
  // Begin chip erase.
  SPI.beginTransaction(spi_settings_);
  digitalWrite(flash_cs_, LOW);
  SPI.transfer(0x60);
  digitalWrite(flash_cs_, HIGH);
  SPI.endTransaction();

  int wait_time = 100; // Wait at most 1 second.
  while (IsBusy() && wait_time > 0) {
    PW_LOG_DEBUG("Device is busy");
    delay(10);
    wait_time--;
  }

  if (wait_time < 0) {
    return pw::Status::DeadlineExceeded();
  }

  return pw::OkStatus();
}

pw::Result<SpiFlash::DeviceId> SpiFlash::GetDeviceIds() {
  uint8_t manufacturer_id[4] = {
      0x9f,    // Read Manufacturer and Device ID Command
      0, 0, 0, // Result values
  };

  // Read the SPI Flash JEDEC ID.
  SPI.beginTransaction(spi_settings_);
  digitalWrite(flash_cs_, LOW);
  SPI.transfer(manufacturer_id, 4);
  digitalWrite(flash_cs_, HIGH);
  SPI.endTransaction();

  PW_LOG_DEBUG("JEDEC ID: %x %x %x", manufacturer_id[1], manufacturer_id[2],
               manufacturer_id[3]);

  // Check for expected values
  if (manufacturer_id[1] == 0xff && manufacturer_id[2] == 0xff &&
      manufacturer_id[3] == 0xff) {
    PW_LOG_ERROR("Error: Unexpected device ID values. SPI bus may not be "
                 "released by the FPGA.");
    return pw::Status::NotFound();
  }

  return SpiFlash::DeviceId{
      .manufacturer_id = manufacturer_id[1],
      .family_code = manufacturer_id[2],
      .product_version = manufacturer_id[3],
  };
}

} // namespace gonk::spi_flash
