// Copyright 2022 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 <cstdint>

#include "app_common/common.h"

#define LIB_CMSIS_CORE 0
#define LIB_PICO_STDIO_SEMIHOSTING 0

#include "FreeRTOS.h"
#include "ft6236/device.h"
#include "hardware/gpio.h"
#include "hardware/pwm.h"
#include "hardware/vreg.h"
#include "icm42670p/device.h"
#include "kudzu_imu_icm42670p/imu.h"
#include "max17048/device.h"
#include "pi4ioe5v6416/device.h"
#include "pico/stdlib.h"
#include "pw_digital_io_rp2040/digital_io.h"
#include "pw_i2c_rp2040/initiator.h"
#include "pw_log/log.h"
#include "pw_pixel_pusher_rp2040_pio/pixel_pusher.h"
#include "pw_spi/chip_selector_digital_out.h"
#include "pw_spi_rp2040/initiator.h"
#include "pw_status/status.h"
#include "pw_sync/borrow.h"
#include "pw_sync/mutex.h"
#include "pw_thread/detached_thread.h"
#include "pw_thread/thread.h"
#include "pw_thread_freertos/context.h"
#include "pw_thread_freertos/options.h"
#include "pw_touchscreen_ft6236/touchscreen.h"

#if defined(DISPLAY_TYPE_ILI9341)
#include "pw_display_driver_ili9341/display_driver.h"
using DisplayDriver = pw::display_driver::DisplayDriverILI9341;
#elif defined(DISPLAY_TYPE_ST7735)
#include "pw_display_driver_st7735/display_driver.h"
using DisplayDriver = pw::display_driver::DisplayDriverST7735;
#elif defined(DISPLAY_TYPE_ST7789)
#include "pw_display_driver_st7789/display_driver.h"
using DisplayDriver = pw::display_driver::DisplayDriverST7789;
#elif defined(DISPLAY_TYPE_ST7789_PIO)
#include "pw_display_driver_st7789/display_driver.h"
using DisplayDriver = pw::display_driver::DisplayDriverST7789;
#else
#error "Undefined display type"
#endif

using Touchscreen = pw::touchscreen::TouchscreenFT6236;

using pw::Status;
using pw::digital_io::Rp2040Config;
using pw::digital_io::Rp2040DigitalIn;
using pw::digital_io::Rp2040DigitalInOut;
using pw::display::Display;
using pw::framebuffer::Framebuffer;
using pw::framebuffer::PixelFormat;
using pw::framebuffer_pool::FramebufferPool;
using pw::pixel_pusher::PixelPusherRp2040Pio;
using pw::spi::Device;
using pw::spi::DigitalOutChipSelector;
using pw::spi::Initiator;
using pw::spi::Rp2040Initiator;
using pw::sync::Borrowable;
using pw::sync::VirtualMutex;

namespace {

// Pico spi0 Pins
#define SPI_PORT spi0

struct SpiValues {
  SpiValues(pw::spi::Config config,
            pw::spi::ChipSelector& selector,
            pw::sync::VirtualMutex& initiator_mutex);

  pw::spi::Rp2040Initiator initiator;
  pw::sync::Borrowable<pw::spi::Initiator> borrowable_initiator;
  pw::spi::Device device;
};

static_assert(DISPLAY_WIDTH > 0);
static_assert(DISPLAY_HEIGHT > 0);

constexpr uint16_t kDisplayScaleFactor = 2;
constexpr uint16_t kFramebufferWidth =
    FRAMEBUFFER_WIDTH >= 0 ? FRAMEBUFFER_WIDTH / kDisplayScaleFactor
                           : DISPLAY_WIDTH / kDisplayScaleFactor;
constexpr uint16_t kFramebufferHeight = DISPLAY_HEIGHT / kDisplayScaleFactor;

constexpr pw::math::Size<uint16_t> kDisplaySize{DISPLAY_WIDTH, DISPLAY_HEIGHT};
constexpr size_t kNumPixels = kFramebufferWidth * kFramebufferHeight;
constexpr uint16_t kFramebufferRowBytes = sizeof(uint16_t) * kFramebufferWidth;

constexpr uint32_t kBaudRate = 31'250'000;
constexpr pw::spi::Config kSpiConfig8Bit{
    .polarity = pw::spi::ClockPolarity::kActiveHigh,
    .phase = pw::spi::ClockPhase::kRisingEdge,
    .bits_per_word = pw::spi::BitsPerWord(8),
    .bit_order = pw::spi::BitOrder::kMsbFirst,
};
constexpr pw::spi::Config kSpiConfig16Bit{
    .polarity = pw::spi::ClockPolarity::kActiveHigh,
    .phase = pw::spi::ClockPhase::kRisingEdge,
    .bits_per_word = pw::spi::BitsPerWord(16),
    .bit_order = pw::spi::BitOrder::kMsbFirst,
};

Rp2040DigitalInOut s_display_dc_pin({
    .pin = DISPLAY_DC_GPIO,
    .polarity = pw::digital_io::Polarity::kActiveHigh,
});
#if DISPLAY_RESET_GPIO != -1
Rp2040DigitalInOut s_display_reset_pin({
    .pin = DISPLAY_RESET_GPIO,
    .polarity = pw::digital_io::Polarity::kActiveLow,
});
#endif
#if DISPLAY_TE_GPIO != -1
Rp2040DigitalIn s_display_tear_effect_pin({
    .pin = DISPLAY_TE_GPIO,
    .polarity = pw::digital_io::Polarity::kActiveHigh,
});
#endif
Rp2040DigitalInOut s_display_cs_pin({
    .pin = DISPLAY_CS_GPIO,
    .polarity = pw::digital_io::Polarity::kActiveLow,
});
DigitalOutChipSelector s_spi_chip_selector(s_display_cs_pin);
Rp2040Initiator s_spi_initiator(SPI_PORT);
VirtualMutex s_spi_initiator_mutex;
Borrowable<Initiator> s_borrowable_spi_initiator(s_spi_initiator,
                                                 s_spi_initiator_mutex);
SpiValues s_spi_8_bit(kSpiConfig8Bit,
                      s_spi_chip_selector,
                      s_spi_initiator_mutex);
SpiValues s_spi_16_bit(kSpiConfig16Bit,
                       s_spi_chip_selector,
                       s_spi_initiator_mutex);

#if USE_PIO
PixelPusherRp2040Pio s_pixel_pusher(DISPLAY_DC_GPIO,
                                    DISPLAY_CS_GPIO,
                                    SPI_MOSI_GPIO,
                                    SPI_CLOCK_GPIO,
                                    DISPLAY_TE_GPIO,
                                    pio0);
#endif
uint16_t s_pixel_data1[kNumPixels];
uint16_t s_pixel_data2[kNumPixels];
const pw::Vector<void*, 2> s_pixel_buffers{s_pixel_data1, s_pixel_data2};
pw::framebuffer_pool::FramebufferPool s_fb_pool({
    .fb_addr = s_pixel_buffers,
    .dimensions = {kFramebufferWidth, kFramebufferHeight},
    .row_bytes = kFramebufferRowBytes,
    .pixel_format = PixelFormat::RGB565,
});
DisplayDriver s_display_driver({
    .data_cmd_gpio = s_display_dc_pin.as<pw::digital_io::DigitalOut>(),
    .spi_cs_gpio = s_display_cs_pin.as<pw::digital_io::DigitalOut>(),
#if DISPLAY_RESET_GPIO != -1
    .reset_gpio = &s_display_reset_pin.as<pw::digital_io::DigitalOut>(),
#else
    .reset_gpio = nullptr,
#endif
#if DISPLAY_TE_GPIO != -1
    .tear_effect_gpio = &s_display_tear_effect_pin,
#else
    .tear_effect_gpio = nullptr,
#endif
    .spi_device_8_bit = s_spi_8_bit.device,
    .spi_device_16_bit = s_spi_16_bit.device,
#if USE_PIO
    .pixel_pusher = &s_pixel_pusher,
#endif
});

#if BACKLIGHT_GPIO != -1
void SetBacklight(uint16_t brightness) {
  pwm_config cfg = pwm_get_default_config();
  pwm_set_wrap(pwm_gpio_to_slice_num(BACKLIGHT_GPIO), 65535);
  pwm_init(pwm_gpio_to_slice_num(BACKLIGHT_GPIO), &cfg, true);
  gpio_set_function(BACKLIGHT_GPIO, GPIO_FUNC_PWM);

  pwm_set_gpio_level(BACKLIGHT_GPIO, brightness);
}
#endif

const uint8_t kStatusPinRed = 23;
const uint8_t kStatusPinGreen = 24;
const uint8_t kStatusPinBlue = 25;

void ConfigStatusRgb() {
  std::array<uint8_t, 3> pwm_pins = {
      kStatusPinRed, kStatusPinGreen, kStatusPinBlue};
  for (auto& pin : pwm_pins) {
    gpio_set_function(pin, GPIO_FUNC_PWM);
    auto slice_num = pwm_gpio_to_slice_num(pin);
    pwm_config cfg = pwm_get_default_config();
    pwm_set_wrap(slice_num, 65535);
    pwm_init(slice_num, &cfg, true);

    pwm_set_gpio_level(pin, 65535);
  }
}

void SetStatusRgb(uint8_t r, uint8_t g, uint8_t b) {
  pwm_set_gpio_level(kStatusPinRed, 65535 - r * r);
  pwm_set_gpio_level(kStatusPinGreen, 65535 - g * g);
  pwm_set_gpio_level(kStatusPinBlue, 65535 - b * b);
}

SpiValues::SpiValues(pw::spi::Config config,
                     pw::spi::ChipSelector& selector,
                     pw::sync::VirtualMutex& initiator_mutex)
    : initiator(SPI_PORT),
      borrowable_initiator(initiator, initiator_mutex),
      device(borrowable_initiator, config, selector) {}

constexpr pw::i2c::PicoInitiator::Config ki2c0Config{
    .i2c_block = 0,
    .baud_rate_bps = 400'000,
    .sda_pin = I2C_BUS0_SDA,
    .scl_pin = I2C_BUS0_SCL,
};
constexpr pw::i2c::PicoInitiator::Config ki2c1Config{
    .i2c_block = 1,
    .baud_rate_bps = 400'000,
    .sda_pin = I2C_BUS1_SDA,
    .scl_pin = I2C_BUS1_SCL,
};
pw::i2c::PicoInitiator i2c0_bus(ki2c0Config);
pw::i2c::PicoInitiator i2c1_bus(ki2c1Config);

pw::pi4ioe5v6416::Device io_expander(i2c1_bus);
kudzu::icm42670p::Device imu(i2c0_bus);
pw::max17048::Device fuel_guage(i2c0_bus);
pw::ft6236::Device touch_screen_controller(i2c0_bus);

static constexpr size_t kDisplayDrawThreadStackWords = 512;
static pw::thread::freertos::StaticContextWithStack<
    kDisplayDrawThreadStackWords>
    display_draw_thread_context;

static constexpr size_t kTouchscreenThreadStackWords = 512;
static pw::thread::freertos::StaticContextWithStack<
    kTouchscreenThreadStackWords>
    touchscreen_thread_context;

Rp2040DigitalInOut s_io_reset_n({
    .pin = 10,
    // IO expander resets when this pin is pulled low.
    .polarity = pw::digital_io::Polarity::kActiveLow,
});
Rp2040DigitalInOut s_io_interrupt_n({
    .pin = 11,
    .polarity = pw::digital_io::Polarity::kActiveLow,
});
Rp2040DigitalInOut s_imu_fsync({
    .pin = 13,
    .polarity = pw::digital_io::Polarity::kActiveHigh,
});

}  // namespace

Status Common::EndOfFrameCallback() {
  // touch_screen_controller.LogControllerInfo();

  if (io_expander.Probe() == pw::OkStatus()) {
    io_expander.LogControllerInfo();
  }

  if (fuel_guage.Probe() == pw::OkStatus()) {
    fuel_guage.LogControllerInfo();
  }

  if (imu.Probe() == pw::OkStatus()) {
    imu.LogControllerInfo();
  }

  return pw::OkStatus();
}

// static
Status Common::Init() {
#if OVERCLOCK_250
  // Overvolt for a stable 250MHz on some RP2040s
  vreg_set_voltage(VREG_VOLTAGE_1_20);
  sleep_ms(10);
  set_sys_clock_khz(250000, false);
#endif

  ConfigStatusRgb();
  // Set to a dim pink.
  SetStatusRgb(32, 12, 32);

  s_display_cs_pin.Enable();
  s_display_dc_pin.Enable();
#if DISPLAY_RESET_GPIO != -1
  s_display_reset_pin.Enable();
#endif

#if DISPLAY_TE_GPIO != -1
  s_display_tear_effect_pin.Enable();
#endif

  i2c0_bus.Enable();
  i2c1_bus.Enable();

  s_io_reset_n.Enable();
  // Disable reset pin - normal operation.
  s_io_reset_n.SetStateInactive();
  s_io_interrupt_n.Enable();

  // IMU FSYNC not used yet
  s_imu_fsync.Enable();

  touch_screen_controller.Enable();
  if (touch_screen_controller.Probe() == pw::OkStatus()) {
    touch_screen_controller.LogControllerInfo();
  }

  io_expander.Enable();
  if (io_expander.Probe() == pw::OkStatus()) {
    io_expander.LogControllerInfo();
  }

  fuel_guage.Enable();
  if (fuel_guage.Probe() == pw::OkStatus()) {
    fuel_guage.LogControllerInfo();
  }

  imu.Enable();
  if (imu.Probe() == pw::OkStatus()) {
    imu.LogControllerInfo();
  }

#if BACKLIGHT_GPIO != -1
  SetBacklight(0xffff);  // Full brightness.
#endif

  unsigned actual_baudrate = spi_init(SPI_PORT, kBaudRate);
  PW_LOG_DEBUG("Actual Baudrate: %u", actual_baudrate);

#if SPI_MISO_GPIO != -1
  gpio_set_function(SPI_MISO_GPIO, GPIO_FUNC_SPI);
#endif
  gpio_set_function(SPI_CLOCK_GPIO, GPIO_FUNC_SPI);
  gpio_set_function(SPI_MOSI_GPIO, GPIO_FUNC_SPI);

#if USE_PIO
  // Init the display before the pixel pusher.
  s_display_driver.Init();
  auto result = s_pixel_pusher.Init(s_fb_pool);
  s_pixel_pusher.SetPixelDouble(true);
  return result;
#else
  return s_display_driver.Init();
#endif
}

// static
pw::display::Display& Common::GetDisplay() {
  static Display s_display(s_display_driver, kDisplaySize, s_fb_pool);
  return s_display;
}

pw::touchscreen::Touchscreen& Common::GetTouchscreen() {
  static Touchscreen s_touchscreen = Touchscreen(&touch_screen_controller);
  return s_touchscreen;
}

kudzu::imu::PollingImu& Common::GetImu() {
  static kudzu::imu::PollingImuICM42670P s_imu(&imu);
  return s_imu;
}

const pw::thread::Options& Common::DisplayDrawThreadOptions() {
  static constexpr auto options =
      pw::thread::freertos::Options()
          .set_name("DisplayDrawThread")
          .set_static_context(display_draw_thread_context)
          // TODO: amontanez - Find a way to better manage priorities.
          .set_priority(static_cast<UBaseType_t>(tskIDLE_PRIORITY + 1));
  return options;
}

const pw::thread::Options& Common::TouchscreenThreadOptions() {
  static constexpr auto options =
      pw::thread::freertos::Options()
          .set_name("TouchscreenThread")
          .set_static_context(touchscreen_thread_context)
          // TODO: amontanez - Find a way to better manage priorities.
          .set_priority(static_cast<UBaseType_t>(tskIDLE_PRIORITY + 1));
  return options;
}
