#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>

#include "defines.h"
#include "configuration.h"


tConfigBlock configBlock;
const uint32_t MAGIC = 3235774467;
const char* CONFIG_SSID = "espconfig";
extern ESP8266WebServer webServer;

bool configSaved = false;


static bool checkAuthentication() {
    Serial.print("User: "); Serial.println(configBlock.confUser);
    Serial.print("Pass: "); Serial.println(configBlock.confPasswd);
	return webServer.authenticate(configBlock.confUser, configBlock.confPasswd);
}

void configServeIndex() {
  bool configValid = (configBlock.magic == MAGIC);

  if (! configValid) {
  configBlock.magic = MAGIC;
    strcpy(configBlock.confUser, "admin");
    strcpy(configBlock.confPasswd, "geheim123");
    strcpy(configBlock.wifiSsid, "test");
    strcpy(configBlock.wifiKey, "geheim");
    strcpy(configBlock.mqttBroker, "broker.hottis.de");
    strcpy(configBlock.mqttUser, "TouchSwitch");
    strcpy(configBlock.mqttPass, "geheim123");
    strcpy(configBlock.mqttClientId, "TouchSwitch");
    configBlock.mqttPort = 8883;
    strcpy(configBlock.mqttTopic, "IoT/TouchSwitch/Press");
    strcpy(configBlock.mqttDebugTopic, "IoT/TouchSwitch/Debug");
    strcpy(configBlock.mqttBaselineTopic, "IoT/TouchSwitch/Baseline");
    configBlock.debugMode = 0;
    configBlock.period = 500;
    configBlock.calibrationTimeout = 20000;
    configBlock.threshold = 10;
  }

  if (! checkAuthentication()) {
    return webServer.requestAuthentication();
  }  


  String buffer =
  "<!doctype html"
  "<html lang=\"en\">"
  "  <head>"
  "    <title>ESP8266 based TouchSwitch</title>"
  "  </head>"
  "  <body>"
  "    <h1>ESP8266 based TouchSwitch - ESP8266 Configuration Page</h1>";
  
  if (configSaved) {
    configSaved = false;
    buffer += "<h2>Configuration saved</h2>";
  }  
  
  buffer +=
  "    <form action=\"/config\" method=\"GET\">"
  "      <table>"
  "        <tr>"
  "          <td>"
  "            <label for\"confUser\">Config Username</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"confUser\" id=\"confUser\" ";
  
  buffer += "    size=\"16\" ";
  buffer += "    value=\"";
  buffer += configBlock.confUser; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"confPasswd\">Config Password</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"confPasswd\" id=\"confPasswd\" ";
  
  buffer += "    size=\"16\" ";
  buffer += "    value=\"";
  buffer += configBlock.confPasswd; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"wifiSsid\">Wifi SSID</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"wifiSsid\" id=\"wifiSsid\" ";
  
  buffer += "    size=\"32\" ";
  buffer += "    value=\"";
  buffer += configBlock.wifiSsid; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"wifiKey\">Wifi Key</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"wifiKey\" id=\"wifiKey\" ";
  
  buffer += "    size=\"64\" ";
  buffer += "    value=\"";
  buffer += configBlock.wifiKey; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"mqttBroker\">MQTT Broker</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"mqttBroker\" id=\"mqttBroker\" ";
  
  buffer += "    size=\"32\" ";
  buffer += "    value=\"";
  buffer += configBlock.mqttBroker; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"mqttUser\">MQTT Username</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"mqttUser\" id=\"mqttUser\" ";
  
  buffer += "    size=\"32\" ";
  buffer += "    value=\"";
  buffer += configBlock.mqttUser; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"mqttPass\">MQTT Password</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"mqttPass\" id=\"mqttPass\" ";
  
  buffer += "    size=\"32\" ";
  buffer += "    value=\"";
  buffer += configBlock.mqttPass; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"mqttClientId\">MQTT ClientId</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"mqttClientId\" id=\"mqttClientId\" ";
  
  buffer += "    size=\"32\" ";
  buffer += "    value=\"";
  buffer += configBlock.mqttClientId; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"mqttPort\">MQTT Port</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"mqttPort\" id=\"mqttPort\" ";
  
  buffer += "    value=\""; 
  buffer += configBlock.mqttPort; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"mqttTopic\">MQTT Topic</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"mqttTopic\" id=\"mqttTopic\" ";
  
  buffer += "    size=\"64\" ";
  buffer += "    value=\"";
  buffer += configBlock.mqttTopic; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"mqttDebugTopic\">MQTT DebugTopic</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"mqttDebugTopic\" id=\"mqttDebugTopic\" ";
  
  buffer += "    size=\"64\" ";
  buffer += "    value=\"";
  buffer += configBlock.mqttDebugTopic; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"mqttBaselineTopic\">MQTT BaselineTopic</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"mqttBaselineTopic\" id=\"mqttBaselineTopic\" ";
  
  buffer += "    size=\"64\" ";
  buffer += "    value=\"";
  buffer += configBlock.mqttBaselineTopic; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"debugMode\">DebugMode</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"debugMode\" id=\"debugMode\" ";
  
  buffer += "    value=\""; 
  buffer += configBlock.debugMode; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"period\">Period</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"period\" id=\"period\" ";
  
  buffer += "    value=\""; 
  buffer += configBlock.period; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"calibrationTimeout\">CalibrationTimeout</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"calibrationTimeout\" id=\"calibrationTimeout\" ";
  
  buffer += "    value=\""; 
  buffer += configBlock.calibrationTimeout; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td>"
  "            <label for\"threshold\">Threshold</label>"
  "          </td><td>"
  "            <input type=\"text\" name=\"threshold\" id=\"threshold\" ";
  
  buffer += "    value=\""; 
  buffer += configBlock.threshold; 
  buffer += "\"";
  
  buffer +=
  "            />"
  "          </td>"
  "        </tr>"
  "        <tr>"
  "          <td colspan=\"2\">"
  "            <button type=\"submit\">Save</button>"
  "          </td>"
  "        </tr>"
  "      </table>"
  "    </form>"
  "  </body>"
  "</html>";

  webServer.send(200, "text/html", buffer);


#ifdef DEBUG
  Serial.println("indexHtml request served");
#endif    
}

void configServeGetConfiguration() {
  if (! checkAuthentication()) {
    return webServer.requestAuthentication();
  }  

  String arg;

  arg = webServer.arg("confUser");
  strcpy(configBlock.confUser, arg.c_str());
  arg = webServer.arg("confPasswd");
  strcpy(configBlock.confPasswd, arg.c_str());
  arg = webServer.arg("wifiSsid");
  strcpy(configBlock.wifiSsid, arg.c_str());
  arg = webServer.arg("wifiKey");
  strcpy(configBlock.wifiKey, arg.c_str());
  arg = webServer.arg("mqttBroker");
  strcpy(configBlock.mqttBroker, arg.c_str());
  arg = webServer.arg("mqttUser");
  strcpy(configBlock.mqttUser, arg.c_str());
  arg = webServer.arg("mqttPass");
  strcpy(configBlock.mqttPass, arg.c_str());
  arg = webServer.arg("mqttClientId");
  strcpy(configBlock.mqttClientId, arg.c_str());
  arg = webServer.arg("mqttPort");
  configBlock.mqttPort = atoi(arg.c_str());
  arg = webServer.arg("mqttTopic");
  strcpy(configBlock.mqttTopic, arg.c_str());
  arg = webServer.arg("mqttDebugTopic");
  strcpy(configBlock.mqttDebugTopic, arg.c_str());
  arg = webServer.arg("mqttBaselineTopic");
  strcpy(configBlock.mqttBaselineTopic, arg.c_str());
  arg = webServer.arg("debugMode");
  configBlock.debugMode = atoi(arg.c_str());
  arg = webServer.arg("period");
  configBlock.period = atoi(arg.c_str());
  arg = webServer.arg("calibrationTimeout");
  configBlock.calibrationTimeout = atoi(arg.c_str());
  arg = webServer.arg("threshold");
  configBlock.threshold = atoi(arg.c_str());
  
  configBlock.magic = MAGIC;
  
  showConfiguration();
  
  EEPROM.begin(512);
  EEPROM.put(EEPROM_ADDR, configBlock);  
  EEPROM.commit();
  
  Serial.println("EEPROM saved");

  configSaved = true;
  webServer.sendHeader("Location", String("/"), true);
  webServer.send(302, "text/plain", "");
  //webServer.send(200, "text/html", "configuration saved");
}
  
void showConfiguration() {
  Serial.println("Configuration is");

  Serial.print("magic = <");
  Serial.print(configBlock.magic);
  Serial.println(">");
    
  Serial.print("confUser = <");
  Serial.print(configBlock.confUser);
  Serial.println(">");
    
  Serial.print("confPasswd = <");
  Serial.print(configBlock.confPasswd);
  Serial.println(">");
    
  Serial.print("wifiSsid = <");
  Serial.print(configBlock.wifiSsid);
  Serial.println(">");
    
  Serial.print("wifiKey = <");
  Serial.print(configBlock.wifiKey);
  Serial.println(">");
    
  Serial.print("mqttBroker = <");
  Serial.print(configBlock.mqttBroker);
  Serial.println(">");
    
  Serial.print("mqttUser = <");
  Serial.print(configBlock.mqttUser);
  Serial.println(">");
    
  Serial.print("mqttPass = <");
  Serial.print(configBlock.mqttPass);
  Serial.println(">");
    
  Serial.print("mqttClientId = <");
  Serial.print(configBlock.mqttClientId);
  Serial.println(">");
    
  Serial.print("mqttPort = <");
  Serial.print(configBlock.mqttPort);
  Serial.println(">");
    
  Serial.print("mqttTopic = <");
  Serial.print(configBlock.mqttTopic);
  Serial.println(">");
    
  Serial.print("mqttDebugTopic = <");
  Serial.print(configBlock.mqttDebugTopic);
  Serial.println(">");
    
  Serial.print("mqttBaselineTopic = <");
  Serial.print(configBlock.mqttBaselineTopic);
  Serial.println(">");
    
  Serial.print("debugMode = <");
  Serial.print(configBlock.debugMode);
  Serial.println(">");
    
  Serial.print("period = <");
  Serial.print(configBlock.period);
  Serial.println(">");
    
  Serial.print("calibrationTimeout = <");
  Serial.print(configBlock.calibrationTimeout);
  Serial.println(">");
    
  Serial.print("threshold = <");
  Serial.print(configBlock.threshold);
  Serial.println(">");
    
  
  Serial.println("---");
}