#include "MotorControl.h"

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

ESP8266WebServer server(80);
MotorControl motorCtl;
const char *webBuffer[1024 * 4];

void wifiSetup()
{
  static const char *ssid = "WLAN";
  static const char *password = "Bau3rWLAN";

  WiFi.begin(ssid, password);
  WiFi.hostname("swimtracker-tester");

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.println("Waiting to connect...");
  }
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void handleGetRoot()
{
  DynamicJsonDocument doc(motorCtl.numCommands() * 16 + 128);
  JsonArray speeds = doc.createNestedArray("speeds");
  JsonArray durations = doc.createNestedArray("durations");
  for (int i = 0; i < motorCtl.numCommands(); ++i)
  {
    speeds.add(motorCtl.speed(i));
    durations.add(motorCtl.duration(i));
  }
  size_t length = serializeJson(doc, webBuffer, sizeof(webBuffer));
  server.send(200, "application/json", (const char *)webBuffer, length);
}

void handlePostRoot()
{
  String postBody = server.arg("plain");
  DynamicJsonDocument doc(postBody.length() * 2 + 256);
  DeserializationError error = deserializeJson(doc, postBody);
  if (error || !doc.containsKey("speeds") || !doc.containsKey("durations"))
    server.send(400, "application/json", "{ \"msg\" : \"Parsing error\" }");
  else
  {
    JsonArray speeds = doc["speeds"].as<JsonArray>();
    JsonArray durations = doc["durations"].as<JsonArray>();
    if (speeds.size() != durations.size())
      server.send(400, "application/json", "{ \"msg\" : \"Arrays have to have same length!\" }");
    else
    {
      motorCtl.clear();
      auto speedIt = speeds.begin();
      auto durationIt = durations.begin();
      for (; speedIt != speeds.end() && durationIt != durations.end(); ++durationIt, ++speedIt)
      {
        motorCtl.addCmd(speedIt->as<float>(), durationIt->as<unsigned long>());
      }
      server.send(200, "application/json", "{ \"msg\" : \"Ok\" }");
    }
  }
}

void setup()
{
  Serial.begin(115200);
  wifiSetup();

  server.on("/", HTTP_GET, handleGetRoot);
  server.on("/", HTTP_POST, handlePostRoot);

  server.begin(); //Start the server
  Serial.println("Server listening");

  motorCtl.begin();
}

void loop()
{
  server.handleClient(); //Handling of incoming client requests
  motorCtl.iteration();
}
