// Copyright 2023 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include <bitset>
#include <cstdint>

#include <Arduino.h>
#include <SPI.h>

#define PW_LOG_LEVEL PW_LOG_LEVEL_INFO
#define PW_LOG_MODULE_NAME "main"

#include "pw_log/log.h"
#include "pw_result/result.h"
#include "pw_string/format.h"

#include "gonk/adc.h"
#include "gonk/fpga_control.h"
#include "gonk/pin_config.h"
#include "gonk/spi_flash.h"

using gonk::adc::Adc;
using gonk::fpga_control::FpgaControl;
using gonk::pin_config::FlashCS;
using gonk::pin_config::FpgaDspiCS;
using gonk::pin_config::FpgaIoMode;
using gonk::pin_config::FpgaIoReset;
using gonk::pin_config::FpgaIoValid;
using gonk::pin_config::ICE40Done;
using gonk::pin_config::PinConfig;
using gonk::pin_config::StatusLed;
using gonk::spi_flash::SpiFlash;

namespace {

PinConfig pin_config = PinConfig();
FpgaControl fpga_control = FpgaControl(&pin_config);
SpiFlash spi_flash =
    SpiFlash(FlashCS, /*baudrate=*/1000000, pin_config.flash_spi);
Adc fpga_adc = Adc(Serial, pin_config.fpga_spi, /*fpga_spi_baudrate=*/7500000,
                   FpgaDspiCS, FpgaIoMode, FpgaIoReset, FpgaIoValid);

void ice40_done_rising_isr() { PW_LOG_DEBUG("ICE40 Done: HIGH"); }

void (*current_task)();

} // namespace

void IdleTask();
void FpgaConfigTask();
void ADCTask();

void IdleTask() {
  static uint32_t last_update = millis();
  static uint32_t this_update = millis();
  static uint16_t update_count = 0;

  this_update = millis();

  // Check for serial input.
  if (Serial.available()) {
    int data_in = Serial.read();
    // Press enter to restart the FPGA config.
    if (data_in == '\n') {
      PW_LOG_INFO("Restarting FPGA Config.");
      current_task = &FpgaConfigTask;
    }
  }

  // Output an idle state heartbeat message each second.
  if (this_update > last_update + 1000) {
    PW_LOG_INFO("Idle update: %d", update_count);

    last_update = this_update;
    update_count = (update_count + 1) % UINT16_MAX;

    // Toggle status LED each loop.
    if (update_count % 2 == 0) {
      digitalWrite(StatusLed, HIGH);
    } else {
      digitalWrite(StatusLed, LOW);
    }
  }
}

void ADCTask() {
  pw::Status update_result = fpga_adc.UpdateContinuousMeasurements();
  if (!update_result.ok()) {
    PW_LOG_ERROR("UpdateContinuousMeasurements() failed");
  } else {
    pw::Status write_result = fpga_adc.WriteMeasurementPacket();
    if (!write_result.ok()) {
      PW_LOG_ERROR("WriteMeasurementPacket failed");
    }
  }
}

void CheckSpiFlash() {
  PW_LOG_INFO("Checking SPI Flash");
  spi_flash.StartFlashSpi();

  pw::Result<SpiFlash::DeviceId> result = spi_flash.GetDeviceIds();
  if (result.ok()) {
    PW_LOG_INFO("SPI Flash JEDEC ID: %x %x %x", result.value().manufacturer_id,
                result.value().family_code, result.value().product_version);
  }
}

void FpgaConfigTask() {
  auto result = fpga_control.StartConfig();
  if (result.ok()) {
    // FPGA has been configure successfully.
    current_task = &ADCTask;
    // Check if SPI flash is readable.
    CheckSpiFlash();
    // Init ADCs
    fpga_adc.InitAdcs();
    fpga_adc.CheckAllAdcs();
    // Select the first five ADC channels.
    fpga_adc.SelectContinuousReadAdcs(0b11111);

    PW_LOG_INFO("Switching to ADC binary log");
    fpga_adc.SetContinuousReadMode();
  } else {
    PW_LOG_INFO("Restarting FPGA Config.");
    current_task = &FpgaConfigTask;
  }
}

int main() {
  // Debug interrupt to watch when ICE40Done goes high.
  attachInterrupt(/*pin=*/ICE40Done, /*callback=*/&ice40_done_rising_isr,
                  /*mode=*/HIGH);

  pin_config.Init();
  pin_config.InitFpgaPins();
  delay(500);

  current_task = &FpgaConfigTask;

  // Start the task loop.
  while (true) {
    current_task();
  }

  PW_UNREACHABLE;
  return 0;
}
