/**
 * @file utility.hpp
 * @author Radim Buráň (xburan03@stud.fit.vutbr.cz)
 */

#ifndef UTILITY_H
#define UTILITY_H
#include <esp_err.h>
#include "nvs.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_sleep.h"
#include "driver/rtc_io.h"
#include "esp_timer.h"

#include "mqtt.hpp"
#include "webserver.hpp"

#include "cJSON.h"

#include "driver/i2c.h"
#include "sht3x.h"
#include "pca9685.h"
#include "DFRobot_AS7341.h"
#include "VL53L0X.h"

static const char* LOG_TAG = "INFO";

#define LED_PIN GPIO_NUM_2
#define PUMP_PIN GPIO_NUM_25
#define BUTTON_PIN GPIO_NUM_27  //GPIO_NUM_13

#define SLEEP_TIMER_US 900000000    //15 minutes to microseconds
#define HOUR_MS 3600000             //1h to ms

#define WATER_TANK_LEVEL_MIN 270
#define WATER_TANK_LEVEL_MAX 100

#define I2C_SDA_PIN GPIO_NUM_21
#define I2C_SCL_PIN GPIO_NUM_22 

#define KEY_NVS_PASSWORD "pwd"
#define KEY_NVS_SSID "ssid"
#define KEY_NVS_DEVICE_ID "devid"

#define KEY_JSON_IN_DATE "date"
#define KEY_JSON_IN_HUMIDITY "hum"
#define KEY_JSON_IN_HUMIDITY_HYSTERESIS "hum_hyst"
#define KEY_JSON_IN_PUMP_CYCLE "pump_cycle"
#define KEY_JSON_IN_LIGHT_UV "luv"
#define KEY_JSON_IN_LIGHT_BLUE "lblue"
#define KEY_JSON_IN_LIGHT_GREEN "lgreen"
#define KEY_JSON_IN_LIGHT_YELLOW "lyellow"
#define KEY_JSON_IN_LIGHT_RED "lred"
#define KEY_JSON_IN_LIGHT_FAR_RED "lfred"
#define KEY_JSON_IN_LIGHT_IR "lir"

#define KEY_JSON_OUT_SOIL_HUMIDITY "soil_hum"
#define KEY_JSON_OUT_AIR_TEMPERATURE "air_temp"
#define KEY_JSON_OUT_AIR_HUMIDITY "air_hum"
#define KEY_JSON_OUT_WATER_LEVEL "water_level"
#define KEY_JSON_OUT_LIGHT "light"

#define BIT_SHT31 0b1
#define BIT_AS7341 0b10
#define BIT_VL53L0X 0b100
#define BIT_SOIL 0b1000
#define BIT_WIFI_ESTABLISHED 0b10000
#define BIT_MQTT_ESTABLISHED 0b100000
#define BIT_PRESET_PARSED  0b1000000
#define BIT_WIFI_MQTT_SENSORS 0b1111111
#define BIT_ACTUATORS_FINISHED 0b10000000
#define BIT_OFFLINE_MODE 0b100000000
#define BIT_OFFLINE_SENSORS_FINISHED 0b100001100 //BIT_OFFLINE_MODE || BIT_VL53L0X || BIT_SOIL
#define BIT_ALL 0b111111111

#define WIFI_AP_SSID "ESP32"
#define WIFI_AP_PWD "1234567890"

#define MQTT_URI "mqtt://185.91.116.162:1883"   //CHANGE ME - MQTT BROKER URI
#define MQTT_TOPIC_SENSORS "esp32/sensors"
#define MQTT_TOPIC_DEVICES "esp32/devices/"
#define MQTT_TOPIC_ALIVE "esp32/alive"

typedef struct {
    uint8_t waterTankLevel;
    uint8_t soilHumidity;
    uint32_t F1;
    uint32_t F2;
    uint32_t F3;
    uint32_t F4;
    uint32_t F5;
    uint32_t F6;
    uint32_t F7;
    uint32_t F8;
} sensorsData_t;

typedef struct {
    uint64_t date;
    uint8_t humidity;
    uint8_t hysteresis;
    uint16_t pumpCycle;
    uint16_t ledUV;
    uint16_t ledBlue;
    uint16_t ledGreen;
    uint16_t ledYellow;
    uint16_t ledRed;
    uint16_t ledDeepRed;
    uint16_t ledIR;
} presetData_t;

long map(long x, long in_min, long in_max, long out_min, long out_max);

char* appendStrings(char* s1, char* s2);

esp_err_t writeString(const char* key, const char* value);
char* readString(const char* key);

esp_err_t writeU64(const char* key, uint64_t value);
uint64_t readU64(const char* key);

esp_err_t writeU8(const char* key, uint8_t value);
uint8_t readU8(const char* key);

void goToSleep();

cJSON* createJsonTemplate();

#endif