#include "WebServer.h"

static AsyncWebServer server(80);

//called when the url is not defined here return 404
static void onRequest(AsyncWebServerRequest *request){
  //Handle Unknown Request
  request->send(404);
}

void WebServer::begin() {
  server.on("/fwd", HTTP_GET, [&](AsyncWebServerRequest *request){
    Serial.println(F("\n Move clock forward"));

    relays->toggle();

    // create json return
    String json = "{";
    json += "\"result\":\"OK\",";
    json += "\"clockName\":\"" + String(modelTime->getClockName()) + "\",";
    json += "\"real_hours\":\""+String(realTime->getHours())+"\",";
    json += "\"real_minutes\":\""+String(realTime->getMinutes())+"\",";
    json += "\"real_seconds\":\""+String(realTime->getSeconds())+"\",";
    json += "\"model_hours\":\""+String(modelTime->getHours())+"\",";
    json += "\"model_minutes\":\""+String(modelTime->getMinutes())+"\",";
    json += "\"model_seconds\":\""+String(modelTime->getSeconds())+"\"";
    json += "}";

    // return json to WebApp
    request->send(200, F("text/json"), json);
    json = String();
  });

  server.on("/clock", HTTP_GET, [&](AsyncWebServerRequest *request){
    // create json return
    String json = "{";
    json += "\"clockName\":\""+String(modelTime->getClockName())+"\",";
    json += "\"clockSpeed\":\""+String(modelTime->getSpeed_modelMsPerRealSecond())+"\",";
    json += "\"relayHoldTime_ms\":\""+String(relays->getHoldTime_ms())+"\",";
    json += "\"relayMinOffTime_ms\":\""+String(relays->getMinOffTime_ms())+"\",";
    /*
    json += "\"displayRefresh_ms\":\""+String(displayRefresh_ms)+"\",";
    json += "\"displayClockNameEvery_ms\":\""+String(displayClockNameEvery_ms)+"\",";
    json += "\"displayClockNameDuration_ms\":\""+String(displayClockNameDuration_ms)+"\",";
    json += "\"doNotShowClockNameBeforeAndAfterMinuteChange_s\":\""+String(doNotShowClockNameBeforeAndAfterMinuteChange_s)+"\",";
    */
    json += "\"real_hours\":\""+String(realTime->getHours())+"\",";
    json += "\"real_minutes\":\""+String(realTime->getMinutes())+"\",";
    json += "\"real_seconds\":\""+String(realTime->getSeconds())+"\",";
    json += "\"model_hours\":\""+String(modelTime->getHours())+"\",";
    json += "\"model_minutes\":\""+String(modelTime->getMinutes())+"\",";
    json += "\"model_seconds\":\""+String(modelTime->getSeconds())+"\"";
    json += "}";

    // return json to WebApp
    request->send(200, F("text/json"), json);
    json = String();
  });

  server.on("/setDT", HTTP_GET, [&](AsyncWebServerRequest *request){
    String h, m, message;
    Serial.println(F("\n Setting displayed time of clock"));

    message = "";
    if (request->hasParam("h")) {
        h = request->getParam("h")->value();
    } else {
        message += "Parameter h for hours missing. ";
    }
    if (request->hasParam("m")) {
        m = request->getParam("m")->value();
    } else {
        message += "Parameter m for minutes missing. ";
    }

    relays->setDisplayedTime(h.toInt(), m.toInt());
    h = String();
    m = String();

    // create json return
    String json = "{";
    if (message.length() > 0) {
      json += "\"result\":\"Error\",";
      json += "\"message\": \"" + message + "\"";
    } else {
      json += "\"result\":\"OK\"";
    }
    json += "}";

    // return json to WebApp
    request->send(200, F("text/json"), json);
    json = String();
    relays->fwdToTime(realTime->getHours(), realTime->getMinutes());
  });

  server.on("/files", HTTP_GET, [&](AsyncWebServerRequest *request){
    Serial.println(F("\n Directory of FS requested"));
    FSInfo fs_info;
    String message = "";

    if (!SPIFFS.info(fs_info)) {
      message += "Cannot get info about file system! ";
    }

    // create json return
    String json = "{";
    if (message.length() > 0) {
      json += "\"result\":\"Error\",";
      json += "\"message\":\"" + message + "\"";
    } else {
      json += "\"result\":\"OK\",";
      json += "\"fsinfo\":{";
        json += "\"totalBytes\":" + String(fs_info.totalBytes) + ",";
        json += "\"usedBytes\":" + String(fs_info.usedBytes) + ",";
        json += "\"blockSize\":" + String(fs_info.blockSize) + ",";
        json += "\"pageSize\":" + String(fs_info.pageSize) + ",";
        json += "\"maxOpenFiles\":" + String(fs_info.maxOpenFiles) + ",";
        json += "\"maxPathLength\":" + String(fs_info.maxPathLength) + ",";
      json += "},";
      json += "\"files\":\"[";
      Dir dir = SPIFFS.openDir("/");
      boolean isFirstEntry = true;
      while (dir.next()) {
        if (isFirstEntry) { isFirstEntry = false; } else { json += ","; }
        json += "{\"filename\":\"" + dir.fileName() + "\",\"size\":" + dir.fileSize() + "}";
      }
      json += "]";
    }
    json += "}";

    // return json to WebApp
    request->send(200, F("text/json"), json);
    json = String();
  });


  server.serveStatic("/", SPIFFS, "/");
  server.onNotFound(onRequest);

  // start the HTTP server
  server.begin();
  Serial.print(F("HTTP server started at: "));
  Serial.println(WiFi.localIP());
  Serial.println("");
}
