////////////////////////////////////////////////////////////////////////////////////////////////////
//ANDRUINO LIBRARY
//A.Scavuzzo
//www.andruino.it
////////////////////////////////////////////////////////////////////////////////////////////////////

#if ETHERNET_SHIELD == 1 || ETHERNET_SHIELD_V2 == 1
byte json_WaitForRequest_and_ParseReceivedRequest(EthernetClient _client, char *ardu_name, char *ardu_pass);
#elif WIFI_ESP8266_SHIELD == 1
byte json_WaitForRequest_and_ParseReceivedRequest(WiFiEspClient _client, char *ardu_name, char *ardu_pass);
#else //MCU_ESP8266 & ARDUINO_MK1010_WIFI
byte json_WaitForRequest_and_ParseReceivedRequest(WiFiClient _client, char *ardu_name, char *ardu_pass);
#endif


#if SERVER_MODE == 1
void server_check_connection () {

  //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  //NETWORK CONNECTION AS SERVER


  _client = _server.available();                              //If Ethernet module has received data, let's decode them



  if (_client) {
    connection_isfar = 0;                                        //used to avoid ddns read during sensor reading
    network_access++;
    Serial.println(F("Rcv connection"));

    unsigned long int http_performance_start = millis();
    Arduino_User_var[2].value = network_access;
    byte clientStatus = json_WaitForRequest_and_ParseReceivedRequest(_client, board_name_array, ARDUINO_PASS);   //buffer the received string in buffer[], parsing the received string, extract username, password, command, action, port
    if (clientStatus == 1) {
      json_PerformRequestedCommand(false, 0);                         //execute the action read above (read, etc)  - false(full json)
    }
    else {
      server_fail_cnt++;
      _client.print(F("{\"error\":["));
      _client.print(clientStatus);
      _client.print(F("]}"));
#if DEBUG_SERIAL_SERVER == 1
      Serial.print(F("\r\nServer error:")); Serial.println(clientStatus);
#endif
    }
    Serial.println(F("\r\nclosing connection"));
    //close previous connection
    _client.flush();
    _client.stop();

    http_server_performance_ms = (unsigned int)((unsigned long int)millis() - (unsigned long int)http_performance_start);
#if DEBUG_SERIAL_SERVER == 1
    Serial.print(F("\r\nhttp_performance: ")); Serial.print(http_server_performance_ms); Serial.println(F("ms"));
#endif
    if (http_server_performance_ms > 4000) {
      server_fail_cnt++;
      server_fail_repeated_cnt++;
#if DEBUG_SERIAL_SERVER == 1
      Serial.print(F("server_fail_cnt: ")); Serial.print(server_fail_cnt); Serial.print(F(", server_fail_repeated_cnt: ")); Serial.println(server_fail_repeated_cnt);
#endif

#if WIFI_ESP8266_SHIELD == 1
      Serial1.println("AT+CIPCLOSE=0");               //close connection
#endif
    } else {
      server_fail_repeated_cnt = 0;
    }
  }

}










//return 1 if the username/password are right
//return 0 if the username/password are wrong or the connection is lost or the 500ms  of timeout occurs
//&cmd=LimAna&port=0&action=0&action2=0&action3=0&action4=0


#if ETHERNET_SHIELD == 1 || ETHERNET_SHIELD_V2 == 1
byte json_WaitForRequest_and_ParseReceivedRequest(EthernetClient _client, char *ardu_name, char *ardu_pass)
#elif WIFI_ESP8266_SHIELD == 1
byte json_WaitForRequest_and_ParseReceivedRequest(WiFiEspClient _client, char *ardu_name, char *ardu_pass)
#else  // MCU_ESP8266 & ARDUINO_MK1010_WIFI
byte json_WaitForRequest_and_ParseReceivedRequest(WiFiClient _client, char *ardu_name, char *ardu_pass)
#endif

{


  char pass[15];    // Limits length to 15 characters
  char user[20];    // Limits length to 20 characters

  int bufferSize = 0;
  unsigned long int StartTime;
  boolean ClientStatus = true;
  boolean Timeout = false;
  boolean currentLineIsBlank = true;
  boolean FoundOnCurrentLine = false;
  boolean AlreadyFound = false;

  StartTime = millis();

  while (ClientStatus && (!Timeout)) {
    if ((millis() - StartTime) > TIMEOUT_RCVCMD) {          //exit if timeout occurs (500ms)
      Timeout = true;
#if DEBUG_SERIAL_JSON == 1
      Serial.println(F("Timeout"));
#endif
      break;
    }
    ClientStatus = _client.connected();
    if (_client.available() && ClientStatus) {
      char c = _client.read();
#if DEBUG_SERIAL_JSON == 1
      Serial.write(c);
#endif
      if (c == '\n' && currentLineIsBlank) {
        // you're starting a new line
#if DEBUG_SERIAL_JSON == 1
        Serial.print(F("\r\nsize: "));
        Serial.println(bufferSize);
#endif

        _client.print(F("HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nConnection: close\r\n\r\n"));
        break;

      }
      if (c == '\n') {
        // you're starting a new line
        currentLineIsBlank = true;

        if (strstr((char *)eth_buffer, "GET /IO") > 0) {
          AlreadyFound = true;
          eth_buffer[bufferSize] = '\0';                             //terninatio
        }

        if (!AlreadyFound) {
          bufferSize = 0;
          eth_buffer[0] = '\0';
        }

      }
      else if (c != '\r') {
        // you've gotten a character on the current line
        if (bufferSize < ETH_TX_RX_MAX_PACKET - 1 &&  AlreadyFound == false) {
          eth_buffer[bufferSize] = c;                             //fill the buffer
          bufferSize++;
        }
        currentLineIsBlank = false;
      }

    }       //if (_client.available() && ClientStatus)
  }


  if (ClientStatus == false || Timeout == true) {
#if DEBUG_SERIAL_JSON == 1
    Serial.println(F("\r\nTimeout or client disconnected"));
#endif
    return 3;
  }

  //http://10.0.1.15:8888/IO.json?user=arduino&pass=andrea&cmd=ReadAll&port=0&action=0&action2=0&action3=0

#if DEBUG_SERIAL_JSON == 1
  Serial.println(eth_buffer);
#endif

  //erase all the ram related to the below vectors
  memset(user, 0, sizeof(user));
  memset(pass, 0, sizeof(pass));
  memset(CmdQueue, 0, sizeof(CmdQueue));


  //VALID HTTP data received
  //GET /IO.json?user=arduino&pass=andrea&cmd=ReadAll&port=0&action=0&action2=0&action3=0&action4=0 HTTP/1.1
  if (strstr(eth_buffer, "GET /IO.json") && strstr(eth_buffer, "HTTP/1.1") && bufferSize > 80) {

    json_SearchKeyGET(eth_buffer, "?user=", user, sizeof(user), "&");
    json_SearchKeyGET(eth_buffer, "&pass=", pass, sizeof(pass), "&");
    json_SearchKeyGET(eth_buffer, "&cmd=", CmdQueue[0].cmd, sizeof(CmdQueue[0].cmd), "&");
    json_SearchKeyGET(eth_buffer, "&port=", CmdQueue[0].port, sizeof(CmdQueue[0].port), "&");
    json_SearchKeyGET(eth_buffer, "&action=", CmdQueue[0].action, sizeof(CmdQueue[0].action), "&");
    json_SearchKeyGET(eth_buffer, "&action2=", CmdQueue[0].action2, sizeof(CmdQueue[0].action2), "&");
    json_SearchKeyGET(eth_buffer, "&action3=", CmdQueue[0].action3, sizeof(CmdQueue[0].action3), "&");
    json_SearchKeyGET(eth_buffer, "&action4=", CmdQueue[0].action4, sizeof(CmdQueue[0].action4), "&");
    json_SearchKeyGET(eth_buffer, "&action5=", CmdQueue[0].action5, sizeof(CmdQueue[0].action5), "&");

  } else {

#if DEBUG_SERIAL_JSON == 1
    Serial.println(F("HTTP request not valid"));
#endif
    return 4;
  }




#if DEBUG_SERIAL_JSON == 1
  if (strcmp(ardu_pass, pass) == 0 && strcmp(ardu_name, user) == 0)     //Check if username and password match
    Serial.println(F("pass and user ok"));
  else
    Serial.println(F("pass and or user NOT OK"));
  Serial.print(F("user="));
  Serial.print(user);
  Serial.print(F(", pass="));
  Serial.print(pass);
  Serial.print(F(", cmd="));
  Serial.print(CmdQueue[0].cmd);
  Serial.print(F(", port="));
  Serial.print(CmdQueue[0].port);
  Serial.print(F(", action="));
  Serial.print(CmdQueue[0].action);
  Serial.print(F(", action2="));
  Serial.print(CmdQueue[0].action2);
  Serial.print(F(", action3="));
  Serial.print(CmdQueue[0].action3);
  Serial.print(F(", action4="));
  Serial.print(CmdQueue[0].action4);
  Serial.print(F(", action5="));
  Serial.println(CmdQueue[0].action5);
#endif


  //check username and password
  if ((strcmp(ardu_pass, pass) == 0 && strcmp(ardu_name, user) == 0)) {    //Check if username and password match
    return 1;
  }
  else {
    return 0;
  }
}


//SERVER_MODE
#endif
