#include "../ESPEasyCore/ESPEasy_backgroundtasks.h"

#include "../../ESPEasy_common.h"

#include "../../ESPEasy-Globals.h"
#include "../DataStructs/TimingStats.h"
#include "../ESPEasyCore/ESPEasyNetwork.h"
#include "../ESPEasyCore/Serial.h"
#include "../Globals/NetworkState.h"
#include "../Globals/Services.h"
#include "../Globals/Settings.h"
#if FEATURE_RTTTL && FEATURE_ANYRTTTL_LIB && FEATURE_ANYRTTTL_ASYNC
#include "../Helpers/Audio.h"
#endif // if FEATURE_RTTTL && FEATURE_ANYRTTTL_LIB && FEATURE_ANYRTTTL_ASYNC
#include "../Helpers/ESPEasy_time_calc.h"
#include "../Helpers/Network.h"
#include "../Helpers/Networking.h"


#if FEATURE_ARDUINO_OTA
#include "../Helpers/OTA.h"
#endif



/*********************************************************************************************\
* run background tasks
\*********************************************************************************************/
bool runningBackgroundTasks = false;
void backgroundtasks()
{
  // checkRAM(F("backgroundtasks"));
  // always start with a yield
  delay(0);

  /*
     // Remove this watchdog feed for now.
     // See https://github.com/letscontrolit/ESPEasy/issues/1722#issuecomment-419659193

   #ifdef ESP32
     // Have to find a similar function to call ESP32's esp_task_wdt_feed();
   #else
     ESP.wdtFeed();
   #endif
   */

  // prevent recursion!
  if (runningBackgroundTasks)
  {
    return;
  }

  // Rate limit calls to run backgroundtasks
  static uint32_t lastRunBackgroundTasks = 0;
  if (timePassedSince(lastRunBackgroundTasks) < 10) return;
  lastRunBackgroundTasks = millis();

  START_TIMER
  #if FEATURE_MDNS || FEATURE_ESPEASY_P2P
  const bool networkConnected = NetworkConnected();
  #else
  NetworkConnected();
  #endif

  runningBackgroundTasks = true;

  /*
     // Not needed anymore, see: https://arduino-esp8266.readthedocs.io/en/latest/faq/readme.html#how-to-clear-tcp-pcbs-in-time-wait-state
     if (networkConnected) {
   #if defined(ESP8266)
      tcpCleanup();
   #endif
     }
   */

  process_serialWriteBuffer();

  if (!UseRTOSMultitasking) {
    serial();

//    if (webserverRunning) {
/*
    {
      START_TIMER
      web_server.handleClient();
      STOP_TIMER(WEBSERVER_HANDLE_CLIENT);
    }
*/
    #if FEATURE_ESPEASY_P2P
    if (networkConnected) {
      checkUDP();
    }
    #endif
  }

  #if FEATURE_DNS_SERVER

  // process DNS, only used if the ESP has no valid WiFi config
  if (dnsServerActive) {
    dnsServer.processNextRequest();
  }
  #endif // if FEATURE_DNS_SERVER

  #if FEATURE_ARDUINO_OTA

  if (Settings.ArduinoOTAEnable) {
    ArduinoOTA_handle();
  }

  // once OTA is triggered, only handle that and dont do other stuff. (otherwise it fails)
  while (ArduinoOTAtriggered)
  {
    delay(0);

    ArduinoOTA_handle();
  }

  #endif // if FEATURE_ARDUINO_OTA

  #if FEATURE_MDNS

  // Allow MDNS processing
  if (networkConnected) {
    # ifdef ESP8266

    // ESP32 does not have an update() function
    MDNS.update();
    # endif // ifdef ESP8266
  }
  #endif // if FEATURE_MDNS

  delay(0);

  #if FEATURE_RTTTL && FEATURE_ANYRTTTL_LIB && FEATURE_ANYRTTTL_ASYNC
  update_rtttl();
  #endif // if FEATURE_RTTTL && FEATURE_ANYRTTTL_LIB && FEATURE_ANYRTTTL_ASYNC

  statusLED(false);

  runningBackgroundTasks = false;
  STOP_TIMER(BACKGROUND_TASKS);
}
