#include "Arduino.h"

#include "nvs_flash.h"
#include <mutex>

#include "ESP32epdx.h"
#include "EPD.h"
//#include "IMAGE.h"
#include "wifi_helper.h"
#include "mqtt_helper.h"

std::mutex epd_mtx;

/*
SPI: SCK = 6 ; MISO = 2 ; MOSI = 7 ; SS = 16
EPD: RES = 22 ; DC = 23 ; CS = 1 ; BUSY = 0
*/

extern "C" void mqtt_event_data_callback_func(char* topic, int topic_len, char* data, int data_len)
{
  if (strncmp(topic, CONFIG_MQTT_TOPIC, topic_len))
    return;
  
  // process
  if (data_len == 5624)
  {
    printf("TOPIC (len: %d) -> %.*s\nMESSAGE (len: %d)\n", topic_len, topic_len, topic, data_len);
    if (epd_mtx.try_lock()) 
    {
      // work
      EPD_HW_Init_Fast();
      EPD_Display((unsigned char *)data);
      EPD_DeepSleep();

      // unlock
      epd_mtx.unlock();
    } 
    else 
    {
      // locked
      return;
    }
  }
}

extern "C" void app_main()
{
  initArduino();

  //Initialize NVS
  esp_err_t ret = nvs_flash_init();
  if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
    ESP_ERROR_CHECK(nvs_flash_erase());
    ret = nvs_flash_init();
  }
  ESP_ERROR_CHECK(ret);

  // Initialize EPD
  EPD_Pin_Init(6, 2, 7, 16,
    22, 23, 1, 0);

  // Connect to WiFi
  connect_wifi();

  // Connect to MQTT broker
  connect_mqtt();

  // Arduino-like setup()

  // Arduino-like loop()
  while (true)
  {
    vTaskDelay(500);
  }

  // WARNING: if program reaches end of function app_main() the MCU will restart.
}