
////////////////////////////////////////////////////////////////////////////////////////////////////
//ANDRUINO LIBRARY
//A.Scavuzzo
//www.andruino.it
////////////////////////////////////////////////////////////////////////////////////////////////////

void ethsetup_network_setup ();
void ethsetup_server_begin (int port_n);

void main_Setup() {
  bool force_captive = false;

  //SETUP
  Serial.println(F("\r\n\r\n#######Start Arduino#######"));
  Serial.print(F("firmware:"));
  char buffer_char[10];
  ftoa_andrea(SKETCH_VERSION, buffer_char);
  Serial.println(buffer_char);

#if SLEEP_MODE == 1
  Serial.print(F("Sleep mode enabled: "));Serial.print(SLEEP_WAKEUP_MIN);Serial.println(F(" sec"));
#endif

  float vcc_arduino = ((float) readVcc()) / 1000.0;
  ADC_STEP = vcc_arduino / (ADC_MAX - 1);
  Serial.print(F("Voltage: "));
  ftoa_andrea(vcc_arduino, buffer_char);
  //dtostrf(vcc_arduino, 5, 3, buffer_char);
  Serial.print(buffer_char); Serial.println(F("Volt"));

#if MCU_ESP8266 == 1
  rst_info *resetInfo;
//    enum rst_reason {
//       REASON_DEFAULT_RST = 0, /* normal startup by power on */
//       REASON_WDT_RST = 1, /* hardware watch dog reset */
//       REASON_EXCEPTION_RST = 2, /* exception reset, GPIO status won’t change */
//       REASON_SOFT_WDT_RST   = 3, /* software watch dog reset, GPIO status won’t change */
//       REASON_SOFT_RESTART = 4, /* software restart ,system_restart , GPIO status won’t change */
//       REASON_DEEP_SLEEP_AWAKE = 5, /* wake up from deep-sleep */
//       REASON_EXT_SYS_RST      = 6 /* external system reset */
    resetInfo = ESP.getResetInfoPtr();
    Serial.print(F("Reset reason: ")); Serial.print(ESP.getResetReason());Serial.print(F(", code: "));Serial.println(resetInfo->reason);
#endif

#if MCU_STM32 == 1
  Serial.print(F("STM32 eeprom lenght: ")); Serial.println(EEPROM.length());
#endif


  //LOAD SETUP DATA FROM EEPROM
  eep_RestoreFromFlash();

  attach_interrupt_pin_reading_timer();


  if (eeprom_read_byteNEW ((FLA_FORCE_CAPTIVE_ADDRESS)) != 1) {
    eeprom_write_byteNEW ((FLA_FORCE_CAPTIVE_ADDRESS), 1);
    force_captive = true;
  }


  //if PIN is not set, enable server mode used to insert user parameters (email, pin, arduino board name, port number)
  if (pin_push_flash == 0 || force_captive) {
    Serial.print(F("Force captive portal"));
    ethsetup_network_setup(true);
  } else {
    ethsetup_network_setup(false);
  }








  //only ethernet
#if ETHERNET_SHIELD == 1 || ETHERNET_SHIELD_V2 == 1
  delay(5000);
#endif

  //Sensors setup
  SetupSensors();

  if (station_connection_ok) {
    if (ethsetup_CheckConnection(andruino_it_ip_address, MAX_RETRIES_NUM))
      http_test_andruino_site = true;
    else
      http_test_andruino_site = false;


/////////////////////////////////////
//send push notification at startup

#if MCU_ESP8266 == 1
    if(resetInfo->reason == 0 || resetInfo->reason == 4 || resetInfo->reason == 6) {

//if silent restart is 0
      if (eeprom_read_byteNEW ((FLA_SILENT_RESTART_ADDRESS)) != 1)
        ethsetup_SetupPush(true);                   //setup push and send power-up notification
      else {
        eeprom_write_byteNEW ((FLA_SILENT_RESTART_ADDRESS), 0);
        ethsetup_SetupPush(false);                  //setup push but don't send power-up notification
      }
    }
#else 
    //if silent restart is 0
    if (eeprom_read_byteNEW ((FLA_SILENT_RESTART_ADDRESS)) != 1)
      ethsetup_SetupPush(true);                   //setup push and send power-up notification
    else {
      eeprom_write_byteNEW ((FLA_SILENT_RESTART_ADDRESS), 0);
      ethsetup_SetupPush(false);                  //setup push but don't send power-up notification
    }
#endif
    
    Serial.println(F("Setup finished, DEVICE CONNECTED SUCCESFULLY"));
#if SERVER_MODE == 1
    ethsetup_server_begin(server_port_number);
#endif
  }

  
  else {
    Serial.println(F("Setup finished, BUT DEVICE IS NOT CONNECTED. Connection setup will retry in one minute"));

#if MCU_ESP8266 == 1
    //check if the reset is by button or power-up, in case enable captive portal to change the wifi setting
    if(resetInfo->reason == REASON_DEFAULT_RST || resetInfo->reason == REASON_EXT_SYS_RST) {
        eeprom_write_byteNEW ((FLA_FORCE_CAPTIVE_ADDRESS), 0);
        //force captive portal
        Serial.print(F("Restart and Force captive portal because connection is fail"));
        Restart(false, false);         //true, increment in flash the fault counter, true SILENT power-up
    }
#endif

#if SLEEP_MODE == 1
    Serial.println(F("Connection error, going in sleep mode")); 
    delay(500);
    ESP.deepSleep(SLEEP_WAKEUP_MIN*60e6/4);     //sleep divided by 4 because previous connection is FAIL
#else
  //se non si connette restart
  Restart(false, true);         //true, increment in flash the fault counter, true SILENT power-up
#endif
  }




#ifdef STARTUP_BLINK_LED_ENABLED
  deattach_interrupt_startup_led_timer();
#endif



#if OTA_ESP8266 == 1 && MCU_ESP8266 == 1
  ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();

#endif



  attach_interrupt_timer();

//WATCHDOG
#if ARDUINO_2560MEGA == 1
//enable watchdog
  wdt_enable(WDTO_8S);
#endif
}
