/*
 * To upload through terminal you can use: curl -F "image=@firmware.bin" http://<ip>:8080/update
 *
 *
 * bin file location on windows: C:\Users\<your username>\AppData\Local\Temp\arduino_build_<id>
 */

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>

#include <WiFiClient.h>
#include <WiFiManager.h>         // WiFiManager from bib manager by tzapu

#include "config.h"
#include "config_user.h"

//*************************************************************************//

ESP8266WebServer httpServer(WEB_UPDATER_HTTP_PORT);
ESP8266HTTPUpdateServer httpUpdater;

String _webUpdater_ip = "127.0.0.1";
String _webUpdater_dev = "unknown";

float _webUpdater_sensValues[VALUES];

#define TR_TD_START_STR "<tr><td>"
#define TR_TD_END_STR   "</td></tr>"
#define TD_TD_MID_STR   "</td><td>"

boolean wuValidData = false;

uint32_t _wifi_reconnect_cnt = 0;

//*************************************************************************//

void setupWebUpdater(String device, String ip)
{
  debug("Starting WebUpdater... " + ip);
  _webUpdater_ip = ip;
  _webUpdater_dev = device;

  httpUpdater.setup(&httpServer);

  httpServer.on("/", showHTMLMain);
#ifndef DISABLE_WIFIMANAGER
  httpServer.on("/resetWifiManager", resetWifiManager);
#endif
#ifdef HOMEBRIDGE_WEBSTAT
  httpServer.on("/hbWebstat", hb_webstat_send);
#endif
#ifdef DEBUG_WINDSPEED_MEASUREMENT
  httpServer.on("/measWind", measureWindspeed);
#endif
#ifdef USE_LOGGER
  httpServer.on("/showlog", showLog);
#endif
  httpServer.begin();

  debug("HTTPUpdateServer ready!");
}

//*************************************************************************//

void doWebUpdater(void)
{
  digitalWrite(D0, HIGH);
  httpServer.handleClient();
}

//*************************************************************************//
#ifdef SHOW_SENSOR_DATA_ON_WEBUPDATER_MAIN_PAGE
void sentWindspeed(float ws)
{
  _webUpdater_sensValues[SENSOR_WINDSPEED] = ws;
}
#endif

void setWifiReconnectCnt(uint32_t wrc)
{
  _wifi_reconnect_cnt = wrc;
}

#ifdef SHOW_SENSOR_DATA_ON_WEBUPDATER_MAIN_PAGE
void setSensorData(float sensorValues[])
{

  for (uint8_t i = 0; i < 5 and wuValidData == false; i++)
  {
    if (sensorValues[i] != 0 and sensorValues[i] != nanf("no value") and (not isnan(sensorValues[i])))
    {
      wuValidData = true; // at least one value is not zero, the data
    }
  }

  for (uint8_t i = 0; i < VALUES; i++)
  {
    if (sensorValues[i] != nanf("no value") and (not isnan(sensorValues[i])))
    {
      // only copy real float values
      //debug(String(i) + "=" + String(sensorValues[i]));
      _webUpdater_sensValues[i] = sensorValues[i];
    }
  }
}
#endif

//*************************************************************************//

void showHTMLMain(void)
{

  String message = "<html><head><title>OKO Weatherstation - " + String(_webUpdater_dev) + "</title>"
                   "<meta http-equiv=\"refresh\" content=\"20\">"
                   "</head><body>"
                   "<br><a href=\"http://" + _webUpdater_ip + ":8080/update\">firmware update</a><br><br>"
#ifdef USE_LOGGER
                   "<br><a href=\"http://" + _webUpdater_ip + ":8080/showlog\">logfile</a><br>"
#endif
#ifdef DEBUG_WINDSPEED_MEASUREMENT
                   "<br><a href=\"http://" + _webUpdater_ip + ":8080/measWind\">manual wind measurement</a><br>"
#endif
#ifdef HOMEBRIDGE_WEBSTAT
                   "<br><a href=\"http://" + _webUpdater_ip + ":8080/hbWebstat\">homebridge websatt</a><br>"
#endif
#ifdef SHOW_SENSOR_DATA_ON_WEBUPDATER_MAIN_PAGE
                   "<br><br><table>"
                   TR_TD_START_STR + "temperature"   + TD_TD_MID_STR + String(_webUpdater_sensValues[SENSOR_TEMPERATURE]) + TR_TD_END_STR
                   TR_TD_START_STR + "humidity"      + TD_TD_MID_STR + String(_webUpdater_sensValues[SENSOR_HUMIDITY])    + TR_TD_END_STR
                   TR_TD_START_STR + "light"         + TD_TD_MID_STR + String(_webUpdater_sensValues[SENSOR_LIGHT])       + TR_TD_END_STR
                   TR_TD_START_STR + "windspeed"     + TD_TD_MID_STR + String(_webUpdater_sensValues[SENSOR_WINDSPEED])   + TR_TD_END_STR
                   TR_TD_START_STR + "pressure"      + TD_TD_MID_STR + String(_webUpdater_sensValues[SENSOR_PRESSURE])    + TR_TD_END_STR
                   TR_TD_START_STR + "batvoltage"    + TD_TD_MID_STR + String(_webUpdater_sensValues[SENSOR_BAT_VOLTAGE]) + TR_TD_END_STR
                   TR_TD_START_STR + "millis"        + TD_TD_MID_STR + String(millis())                                   + TR_TD_END_STR
                   TR_TD_START_STR + "valid"         + TD_TD_MID_STR + String(wuValidData)                                + TR_TD_END_STR
                   TR_TD_START_STR + "wifi rssi"     + TD_TD_MID_STR + WiFi.RSSI()                                        + TR_TD_END_STR
                   TR_TD_START_STR + "wifi rec cnt"  + TD_TD_MID_STR + String(_wifi_reconnect_cnt)                        + TR_TD_END_STR
                   "</table>"
#endif
#ifndef DISABLE_WIFIMANAGER
                   "<br><br><br><br><br><a href=\"http://" + _webUpdater_ip + ":8080/resetWifiManager\">reset WiFi Manager</a><br>"
#endif
                   "</body></html>";

  httpServer.send(200, "text/html", message);
}

//*************************************************************************//

#ifdef HOMEBRIDGE_WEBSTAT
void hb_webstat_send(void)
{

  String msg = hb_ws_msg_start +
              hb_ws_msg_temp +
              String(_webUpdater_sensValues[SENSOR_TEMPERATURE], 2) +
              ", " +
              hb_ws_msg_humi +
              String(_webUpdater_sensValues[SENSOR_HUMIDITY], 2) +
              ", " +
              hb_ws_msg_light +
              String(_webUpdater_sensValues[SENSOR_LIGHT], 0) + // The light level for the homebridge-http-lux2 plugin is only able to parse integer values
              ", " +
              hb_ws_msg_windspeed +
              String(_webUpdater_sensValues[SENSOR_WINDSPEED], 2) +
              ", " +
              hb_ws_msg_pressure +
              String(_webUpdater_sensValues[SENSOR_PRESSURE], 2) +
              ", " +
              hb_ws_msg_timestamp +
              String(millis()) +
              ", " +
              hb_ws_msg_valid +
              String(wuValidData) +
              hb_ws_msg_end;

  httpServer.send(200, "text/html", msg);
}
#endif

//*************************************************************************//

#ifndef DISABLE_WIFIMANAGER

void resetWifiManager()
{

  String message = "<html><head><title>OKO Weatherstation - " + String(_webUpdater_dev) + " - reset WiFi manager</title>"
                   "<meta http-equiv=\"refresh\" content=\"20\">"
                   "</head><body>"
                   "Reset WifiManager config.<br>"
                   "Rebooting...<br>"
                   "</body></html>";

  httpServer.send(200, "text/html", message);

  // Erase WiFi Credentials, enable, compile, flash, disable and reflash.
  WiFiManager wifiManager;
  wifiManager.resetSettings();

  delay(5000);

  // manual reset after restart is required
  ESP.restart();
}

#endif

//*************************************************************************//

#ifdef DEBUG_WINDSPEED_MEASUREMENT
#ifdef SENSOR_WIND
void measureWindspeed()
{

  // read from windspeed sensorSTATUS_LED_PIN
  digitalWrite(STATUS_LED_PIN, HIGH);
  debug("Starting windspeed measurement");
  float tmp_windspeed = wind_speed();
  digitalWrite(STATUS_LED_PIN, LOW);

  String message = "<html><head><title>OKO Weatherstation - " + String(_webUpdater_dev) + " - manual wind measurement</title>"
                   "</head><body>"
                   "Windsensor measurement result: " + String(tmp_windspeed) + "<br>"
                   "</body></html>";

  httpServer.send(200, "text/html", message);

}
#endif
#endif

//*************************************************************************//

#ifdef USE_LOGGER

#define LOGFILE_SIZE 25

String logfile[LOGFILE_SIZE];

uint16_t logger_pos = 0;

void logdata(String s)
{
  logfile[logger_pos] = s;
  logger_pos++;

  if (logger_pos > LOGFILE_SIZE -1)
  {
    for (uint16_t i = 1; i < LOGFILE_SIZE; i++)
    {
      logfile[i-1] = logfile[i]; // overwrite previous element with current element
    }
    logger_pos--; // reduce the position in the log
  }
}

void showLog()
{
  String message = "<html><head><title>OKO Weatherstation - " + String(_webUpdater_dev) + " - logfile</title>"
                   "<meta http-equiv=\"refresh\" content=\"5\">"
                   "</head><body>"
                   "Logfile data:<br>";

  for (uint16_t lp = 0; lp < logger_pos; lp++)
  {
    message = message + logfile[lp] + "<br>";
  }

  message = message + "</body></html>";

  httpServer.send(200, "text/html", message);
}

#endif

//*************************************************************************//
