#pragma once

// #define DEBUG


// ****************************************
#define WAIT_FOR_WIFI               10     // in seconds
#define MQTT_DEVICE_IDENTIFIER      String(WiFi.macAddress())
#define MQTT_TOP_LEVEL_TOPIC        "papio"

// configuration template:

#if DEVICE_ID == 29
  #define BOARD_TYPE                2
  #define HOSTNAME                  "esp32029"
  #define ROLE_NAME                 "GW1 Hall"
  #define LED_GPIO_SENSORS          5   // RED
  #define LED_GPIO_GATEWAY          6   // GREEN
  #define LED_GPIO_STANDBY          6   // BLUE


  #define LED_GPIO_SENSORS_USE_PWM  1
  #define LED_GPIO_SENSORS_PWM_DC   10

  #define LED_GPIO_GATEWAY_USE_PWM  1
  #define LED_GPIO_GATEWAY_PWM_DC   10

  #define LED_GPIO_STANDBY_USE_PWM  1
  #define LED_GPIO_STANDBY_PWM_DC   10

  #define PUSH_BUTTON_GPIO          0  // to control ESP
  #define PUSH_BUTTON_GPIO_ACT    LOW  // HIGH or LOW, HIGH = 1, LOW = 0, 0 if not defined (so default)

  uint8_t FixedMACAddress[] =       {0x2A, 0xFF, 0x01, 0x01, 0x01, 0x29};
  
  #define OTA_ACTIVE                1

  #define COMMAND_QUEUE_TIMEOUT_S   2* 60 * 60  // 2h, in seconds, clear the commands queue for sender after timeout

  #define USE_WEB_SERIAL            1
  #define CP_TIMEOUT_S              180

  // for ESPnow
  #define ESPNOW_ENABLED              1 // 1-enable ESPnow, 0 or nothing - NO ESPnow capabilities

  // for LoRa
  #define LORA_ENABLED                0 // 1-enable LoRa, 0 or nothing - NO LoRa capabilities
  // #define LORA_GPIO_ENABLE_3V         19   // comment out if not in use - don't use "0" here unless you mean GPIO=0 - mandatory for I2C devices on new boards
  #define LORA_GPIO_MISO              20  // - BLUE
  #define LORA_GPIO_MOSI              17  // - GREEN
  #define LORA_GPIO_CLOCK             18  // - BROWN
  #define LORA_GPIO_SS                14  // - YELLOW, SS/NSS/CS:
  #define LORA_GPIO_RST               15  // - ORANGE
  #define LORA_GPIO_DIO0              16  // - VIOLET

/* TESTING 
  // MHZ19
  #define USE_MHZ19_CO2             1     // use "0" to disable
  #define RX_PIN                    11    // Rx pin which the MHZ19 Tx pin is attached to - BROWN
  #define TX_PIN                    10    // Tx pin which the MHZ19 Rx pin is attached to - BLACK
  #define BAUDRATE                 9600   // Device to MH-Z19 Serial baudrate (should not be changed)
  #define MHZ19_AUTO_CALIBRATION    1   // don't autocalibrate MHZ19
  #define CO2_UPDATE_INTERVAL_S     120   // 120, how often to measure CO2 - every 2m as per datasheet
  #define CO2_PREHEAT_TIME_S        180   // 180, initial preheat time as per datasheet 
  #define MIN_CO2                   330   // 330, invalid reading below 330 ppm as per datasheet (400 +-50 +-5%)
  #define CO2_CALIBRATE_TIME_S      40 * 60  // 20*60=20min as per datasheet

  #define MEASURE_LUX               1
  #define MEASURE_LUX_GPIO          11
  #define LUX_MAX_RAW_READING       7800  // resistors specific max value - variable as each sensor is done with different voltage divider
  #define LUX_MAX_RAW_MAPPED_READING 1000 // TEPT4400 can measure only up to 1000lx then it gets satturated
  #define LUX_MIN_RAW_READING       0     // set it to min shown when TEPT4400 is completely covered to get 0lx 
*/

  #pragma message "compilation for: ESPnow_esp32029_gw1"


#elif DEVICE_ID == 30
  #define BOARD_TYPE                2
  #define HOSTNAME                  "esp32030"
  #define ROLE_NAME                 "GW2 Garage"
  #define LED_GPIO_SENSORS          3   // RED
  #define LED_GPIO_GATEWAY          5   // GREEN
  #define LED_GPIO_STANDBY          2   // BLUE

  #define LED_GPIO_SENSORS_USE_PWM  1
  #define LED_GPIO_SENSORS_PWM_DC   10

  #define LED_GPIO_GATEWAY_USE_PWM  1
  #define LED_GPIO_GATEWAY_PWM_DC   10

  #define LED_GPIO_STANDBY_USE_PWM  1
  #define LED_GPIO_STANDBY_PWM_DC   10

  #define PUSH_BUTTON_GPIO          0  // to control ESP
  #define PUSH_BUTTON_GPIO_ACT    LOW  // HIGH or LOW, HIGH = 1, LOW = 0, 0 if not defined (so default)

  uint8_t FixedMACAddress[] =       {0x2A, 0xFF, 0x01, 0x01, 0x01, 0x30};
  
  #define OTA_ACTIVE                1

  #define COMMAND_QUEUE_TIMEOUT_S   2* 60 * 60  // 2h, in seconds, clear the commands queue for sender after timeout

  #define USE_WEB_SERIAL            1
  #define CP_TIMEOUT_S              180

  // for ESPnow
  #define ESPNOW_ENABLED            1  // 1-enable ESPnow, 0 or nothing - NO ESPnow capabilities

  #pragma message "compilation for: ESPnow_esp32030_gw2"

#elif DEVICE_ID == 27
  #define BOARD_TYPE                2
  #define HOSTNAME                  "esp32027"
  #define ROLE_NAME                 "GW3 Bedroom"
  #define LED_GPIO_SENSORS          2   // RED
  #define LED_GPIO_GATEWAY          4   // GREEN
  #define LED_GPIO_STANDBY          6   // BLUE

  #define PUSH_BUTTON_GPIO          0  // to control ESP
  #define PUSH_BUTTON_GPIO_ACT    LOW  // HIGH or LOW, HIGH = 1, LOW = 0, 0 if not defined (so default)
  
  #define LED_GPIO_SENSORS_USE_PWM  1
  #define LED_GPIO_SENSORS_PWM_DC   10

  #define LED_GPIO_GATEWAY_USE_PWM  1
  #define LED_GPIO_GATEWAY_PWM_DC   10

  #define LED_GPIO_STANDBY_USE_PWM  1
  #define LED_GPIO_STANDBY_PWM_DC   10

  // #define PUSH_BUTTON_GPIO          0  // to control ESP
  // #define PUSH_BUTTON_GPIO_ACT    LOW  // HIGH or LOW, HIGH = 1, LOW = 0, 0 if not defined (so default)

  uint8_t FixedMACAddress[] =       {0x2A, 0xFF, 0x01, 0x01, 0x01, 0x27};
  
  #define OTA_ACTIVE                1

  #define COMMAND_QUEUE_TIMEOUT_S   2* 60 * 60  // 2h, in seconds, clear the commands queue for sender after timeout

  #define USE_INFLUXDB              0
  #define INFLUXDB_URL              "http://ip-here:8086"
  #define INFLUXDB_TOKEN            "passwordshere"
  #define INFLUXDB_ORG              "test-org"
  #define INFLUXDB_BUCKET           "test_bucket"
  #define MY_TIME_ZONE              "GMT0BST,M3.5.0/1,M10.5.0" 

  #define USE_WEB_SERIAL            1
  #define CP_TIMEOUT_S              180

  // for ESPnow
  #define ESPNOW_ENABLED            1  // 1-enable ESPnow, 0 or nothing - NO ESPnow capabilities

  #define MEASURE_LUX               1
  #define MEASURE_LUX_GPIO          11
  #define LUX_MAX_RAW_READING       7800  // resistors specific max value - variable as each sensor is done with different voltage divider
  #define LUX_MAX_RAW_MAPPED_READING 1000 // TEPT4400 can measure only up to 1000lx then it gets satturated
  #define LUX_MIN_RAW_READING       0     // set it to min shown when TEPT4400 is completely covered to get 0lx 


  #pragma message "compilation for: ESPnow_esp32027_gw3" 


// // esp32029 built on esp32 wrover - it works, LoRa not tested 
// #elif DEVICE_ID == 45     // wrover
//   #define BOARD_TYPE                1
//   #define HOSTNAME                  "esp32045"
//   #define ROLE_NAME                 "GW4 test"
//   #define LED_GPIO_SENSORS          19   // RED
//   #define LED_GPIO_GATEWAY          21   // GREEN
//   #define LED_GPIO_STANDBY          21   // BLUE


//   #define LED_GPIO_SENSORS_USE_PWM  1
//   #define LED_GPIO_SENSORS_PWM_DC   10

//   #define LED_GPIO_GATEWAY_USE_PWM  1
//   #define LED_GPIO_GATEWAY_PWM_DC   10

//   #define LED_GPIO_STANDBY_USE_PWM  1
//   #define LED_GPIO_STANDBY_PWM_DC   10

//   #define PUSH_BUTTON_GPIO          0  // to control ESP
//   #define PUSH_BUTTON_GPIO_ACT    LOW  // HIGH or LOW, HIGH = 1, LOW = 0, 0 if not defined (so default)

//   uint8_t FixedMACAddress[] =       {0x2A, 0xFF, 0x01, 0x01, 0x01, 0x45};
  
//   #define OTA_ACTIVE                1

//   #define COMMAND_QUEUE_TIMEOUT_S   2* 60 * 60  // 2h, in seconds, clear the commands queue for sender after timeout

//   #define USE_WEB_SERIAL            1
//   #define CP_TIMEOUT_S              180

//   // for ESPnow
//   #define ESPNOW_ENABLED              1 // 1-enable ESPnow, 0 or nothing - NO ESPnow capabilities

//   #pragma message "compilation for: ESPnow_esp32045"



// S2 
#elif DEVICE_ID == 92
  #define BOARD_TYPE                2
  #define HOSTNAME                  "esp32092"
  #define ROLE_NAME                 "gw92-test"
  #define LED_GPIO_SENSORS          5   // RED
  #define LED_GPIO_GATEWAY          5   // GREEN
  #define LED_GPIO_STANDBY          6   // BLUE

  #define PUSH_BUTTON_GPIO          10  // to control ESP
  #define PUSH_BUTTON_GPIO_ACT    LOW  // HIGH or LOW, HIGH = 1, LOW = 0, 0 if not defined (so default)

  // #define PUSH_BUTTON_GPIO          0  // to control ESP
  // #define PUSH_BUTTON_GPIO_ACT    LOW  // HIGH or LOW, HIGH = 1, LOW = 0, 0 if not defined (so default)

  uint8_t FixedMACAddress[] =       {0x2A, 0xFF, 0x01, 0x01, 0x01, 0x92};
  
  #define OTA_ACTIVE                0

  #define COMMAND_QUEUE_TIMEOUT_S   2* 60 * 60  // 2h, in seconds, clear the commands queue for sender after timeout

  #define USE_WEB_SERIAL            0
  #define CP_TIMEOUT_S              180

  // for ESPnow
  #define ESPNOW_ENABLED            1  // 1-enable ESPnow, 0 or nothing - NO ESPnow capabilities

  #pragma message "compilation for: ESPnow_esp32092-gwtest"


#else
  #error "Wrong DEVICE_ID chosen"
#endif
// DEVICE CUSTOM SETTINGS END

// check if LoRa and ESPnow
#if ((LORA_ENABLED == 1) and (ESPNOW_ENABLED == 1))
  #error "both LoRa and ESPnow cannot work together, choose only one"
#endif

// check if neither LoRa nor ESPnow
#if ((LORA_ENABLED == 0) and (ESPNOW_ENABLED == 0))
  #error "both LoRa and ESPnow are DISABLED, enable one"
#endif

// 
#ifndef LED_GPIO_GATEWAY
  #warning "LED_GPIO_GATEWAY must exist for both: connect_wifi() and to indicate the Captive Portal"
#endif

// for PubSubClient:
// it is used in: mqttc.setBufferSize(MQTT_PAYLOAD_MAX_SIZE); to increase max packet size
//default is 256 but it is not enough in this program - check debug in case of issue
#define MQTT_PAYLOAD_MAX_SIZE       1024

// for ArduinoJson
#define JSON_CONFIG_SIZE            1024  // config is bigger than payload due to device information
#define JSON_PAYLOAD_SIZE           512

// mqtt - how many attempts to connect to MQTT broker before restarting
#define MAX_MQTT_ERROR              30  // in times, used in mqtt.reconnect as well as in loop to check if MQTT is ok
                                         // and if not it restarts the ESP

// queue size for incomming data from sensors, whe queue is full no more data is gathered until there is free space in the queue
// set it to as much as many sensor devices you have so each one gets into the queue at least once. Unless some are very frequent (i.e. motion)
#define MAX_QUEUE_COUNT             100  //100
#define MAX_QUEUE_COMMANDS_COUNT    100  

// how often to update HA on GW status
#define HEARTBEAT_INTERVAL_S        15    //10 in seconds

// availability topic and not available payload
#define AVAILABILITY_TOPIC          MQTT_TOP_LEVEL_TOPIC "/" HOSTNAME "/available"
#define NOT_AVAILABLE_PAYLOAD       "{\"available\":\"offline\"}"

// FW update timeout
#define FW_UPDATE_TIME_S            180   // in seconds - 3 minutes shall be enough

// LED PWM settings
#ifdef LED_GPIO_STANDBY_USE_PWM
  #define LED_GPIO_STANDBY_PWM_CHANNEL    1
  #define LED_GPIO_STANDBY_PWM_RESOLUTION 8
  #define LED_GPIO_STANDBY_PWM_FREQ       5000
  #define LED_GPIO_STANDBY_MIN_DC         0
  #define LED_GPIO_STANDBY_MAX_DC         255
#endif

#ifdef LED_GPIO_SENSORS_USE_PWM
  #define LED_GPIO_SENSORS_PWM_CHANNEL    2
  #define LED_GPIO_SENSORS_PWM_RESOLUTION 8
  #define LED_GPIO_SENSORS_PWM_FREQ       5000
  #define LED_GPIO_SENSORS_MIN_DC         0
  #define LED_GPIO_SENSORS_MAX_DC         255
#endif

#ifdef LED_GPIO_GATEWAY_USE_PWM
  #define LED_GPIO_GATEWAY_PWM_CHANNEL    3
  #define LED_GPIO_GATEWAY_PWM_RESOLUTION 8
  #define LED_GPIO_GATEWAY_PWM_FREQ       5000
  #define LED_GPIO_GATEWAY_MIN_DC         0
  #define LED_GPIO_GATEWAY_MAX_DC         255
#endif

#define MAX_BAD_BOOT_COUNT                30   // after it is reached, it will erase nvs and then start Captive Portal with null values


// assigning MODEL and checking if proper board is selected
#define PRINT_COMPILER_MESSAGES // comment out to disable messages in precompiler
#ifndef BOARD_TYPE
  #error BOARD_TYPE not defined
#else
  #if (BOARD_TYPE == 1) and (!defined(CONFIG_IDF_TARGET_ESP32))
    #error wrong board selected in Arduino - choose ESP32DEV
  #endif
  #if (BOARD_TYPE == 2) and (!defined(CONFIG_IDF_TARGET_ESP32S2))
    #error wrong board selected in Arduino - choose S2
  #endif
  #if (BOARD_TYPE == 3) and (!defined(CONFIG_IDF_TARGET_ESP32S3))
    #error wrong board selected in Arduino - choose S3
  #endif
  #if (BOARD_TYPE == 4) and (!defined(CONFIG_IDF_TARGET_ESP32C3))
    #error wrong board selected in Arduino - choose C3
  #endif

  #if (BOARD_TYPE == 1)
    #define MODEL "ESP32"
    #ifdef PRINT_COMPILER_MESSAGES
      #pragma message "chosen BOARD_TYPE = ESP32"
    #endif
  #elif (BOARD_TYPE == 2)
    #define MODEL "ESP32S2"
    #ifdef PRINT_COMPILER_MESSAGES
      #pragma message "chosen BOARD_TYPE = ESP32S2"
    #endif
  #elif (BOARD_TYPE == 3)
    #define MODEL "ESP32S3"
    #ifdef PRINT_COMPILER_MESSAGES
      #pragma message "chosen BOARD_TYPE = ESP32S3"
    #endif
  #elif (BOARD_TYPE == 4)
    #define MODEL "ESP32C3"
    #ifdef PRINT_COMPILER_MESSAGES
      #pragma message "chosen BOARD_TYPE = ESP32C3"
    #endif
  #else
    #error BOARD_TYPE not defined
  #endif

  #if (ESPNOW_ENABLED == 1)
    #define DEV_MODEL (String(MODEL) + ", ESPnow, WiFi")
  #else 
    #define DEV_MODEL (String(MODEL) + ", LoRa, WiFi")
  #endif 

// to retain values or not
#define RETAIN_SENSORS_DATA     1     // 0 or comment out to disable
#define RETAIN_GATEWAY_DATA     1     // 0 or comment out to disable

#endif
// assigning MODEL and checking if proper board is selected END


// ======================== FLAGS used for creating sensors/entities on HA =====================
/*
  uint32_t
  0000  0000  0000  0000  0000  0000  0000  0000
*/
#define FLAG_1_BATTERY_VOLTS          1 << 0   // 1         // 0b1
#define FLAG_2_BATTERY_PERCENT        1 << 1   // 2         // 0b10
#define FLAG_3_BATTERY_CHARGING       1 << 2   // 4         // 0b100...
#define FLAG_4_CHARGING               1 << 3   // 8

#define FLAG_5_TEMPERATURE            1 << 4   // 16
#define FLAG_6_HUMIDITY               1 << 5   // 32
#define FLAG_7_LUX                    1 << 6   // 64
#define FLAG_8_LIGHT_HIGHSENS         1 << 7   // 128
 
#define FLAG_9_BUTTON_PRESSED         1 << 8   // 256
#define FLAG_10_V1                    1 << 9   // 512
#define FLAG_11_I1                    1 << 10  // 1024
#define FLAG_12_P1                    1 << 11  // 2048

#define FLAG_13_V2                    1 << 12  // 4096          // sensor not created yet in mqtt_publish_sensors_data.h
#define FLAG_14_I2                    1 << 13  // 8192          // sensor not created yet in mqtt_publish_sensors_data.h
#define FLAG_15_P2                    1 << 14  // 16384         // sensor not created yet in mqtt_publish_sensors_data.h
#define FLAG_16_V3                    1 << 15  // 32768         // sensor not created yet in mqtt_publish_sensors_data.h

#define FLAG_17_I3                    1 << 16  // 65536         // sensor not created yet in mqtt_publish_sensors_data.h
#define FLAG_18_P3                    1 << 17  // 131072        // sensor not created yet in mqtt_publish_sensors_data.h
#define FLAG_19_MOTION                1 << 18  // 262144
// #define FLAG_20_                      1 << 19  // 524288
// ======================== FLAGS used for creating sensors/entities on HA END =================

