#include <stdlib.h>
#include "ELM327.h"
#include "SIM808.h"

#define APN_HOST "internet.vodafone.ro"
#define APN_USER "internet.vodafone.ro"
#define APN_PASS "vodafone"


uint8_t uart1Response;
uint16_t SIM808_timeout_ms = 1000;
char bufferUart3[128];
uint16_t standby_counter_start = 0;
uint8_t standby = 0;
uint8_t carWasOnline = 0;

void setup() {
    // Start Uart1 & UART3
    Serial_begin(38400);
    SerialUart3_begin(9600);

    while (!Serial) {

    }

    while (!SerialUart3) {

    }

   // GPIO SETUP

    GPIO_setup();
    delay(100);

    GPIO_WriteHigh(GPIOG, GPIO_PIN_1);
    GPIO_WriteHigh(GPIOA, GPIO_PIN_3);
    GPIO_WriteHigh(GPIOB, GPIO_PIN_0);

    delay(2000);

    GPIO_WriteLow(GPIOG, GPIO_PIN_1);
    delay(1000);

    GPIO_WriteHigh(GPIOG, GPIO_PIN_1);
    delay(3000);

    //initializeObdElm();
    initializeSim808();

    // Test uart communication
    //sendMsgUart1();
}
void initializeSim808() {
    delay(3000);
    establishContact();
    setDebugOn();
    delay(10000);
    setCREG();
    setCGATT();
    setCANT();
    delay(10000);
    delay(500);
    enableGPS();

    setupAPN1();
    setupAPN2();
    setupAPN3();
}
void initializeObdElm() {
  ELM327_begin('0', 40);


  ELM327_sendCommand("STVCAL");
    delay(1000);
  ELM327_sendCommand("STSLVLW >13.10, 5");
    delay(1000);
    ELM327_sendCommand("STSLVLS <13.00, 5");
    delay(1000);

  ELM327_sendCommand("STSLVL on,on");
    delay(1000);
    ELM327_sendCommand("STSLCS");
    delay(1000);
}

// Test initialization functions START
void sendMsgUart1() {
  Serial_println_s("Trimitem in UART1");
  delay(200);
}

void sendMsgUart3() {
  SerialUart3_println_s("Trimitem in UART3");
  delay(200);
}

// Test initialization functions END

// SIM808 functions
void establishContact() {
    SerialUart3_println_s("AT");
}


void setDebugOn()
{

    SerialUart3_println_s("AT+CMEE=2");
    delay(100);
    SerialUart3_println_s("AT+CEER");
    delay(100);
}


void setCREG()
{

    SerialUart3_println_s("AT+CREG=1");
    delay(100);
}


void setCGATT()
{

    SerialUart3_println_s("AT+CGATT=1");
    delay(100);
}


void setCANT()
{

    SerialUart3_println_s("AT+CANT=1,1,10");
    delay(100);
}


void enableGPS()
{

    SerialUart3_println_s("AT+CGPSPWR=1");
    delay(10000);
    SerialUart3_println_s("AT+CGPSSTATUS?");
    delay(100);
    SerialUart3_println_s("AT+CGPSINF=?");
}

void setupAPN1()
{

    SerialUart3_println_s("AT+SAPBR=3,1,\"Contype\", \"GPRS\"");
    delay(100);
}

void setupVodafoneAPN()
{

    SerialUart3_println_s("AT+SAPBR=3,1,\"APN\", \"vodafone\"");
    delay(100);
}

void setupAPN2()
{

    SerialUart3_println_s("AT+CSTT=\"internet.vodafone.ro\",\"internet.vodafone.ro\",\"vodafone\"");
    delay(100);

}

void setupAPN3()
{

    SerialUart3_println_s("AT+SAPBR=1,1");
    delay(1000);
    SerialUart3_println_s("AT+SAPBR=2,1");
    delay(1000);
    SerialUart3_println_s("AT+CIFSR");
}


uint8_t checkTimeout(uint32_t previousTime) {

    uint32_t currentTime = millis();
    if ((currentTime - previousTime) >= SIM808_timeout_ms)
        return 1;
    return 0;
}

char* SIM808_sendCommand(char *cmd) {
    char *payloadUart3;
    uint16_t PAYLOAD_LEN_UART3;
    uint16_t recBytes;
    uint32_t currentTime;
    uint32_t previousTime;

    uint8_t counter = 0;

    for (byte i = 0; i < PAYLOAD_LEN_UART3; i++)
        payloadUart3[i] = '\0';

    // reset input buffer and number of received bytes
    recBytes = 0;
//    while (SerialUart3_available()) {
//        SerialUart3_read();
//    }

    previousTime = millis();
    currentTime = previousTime;
    SerialUart3_println_s(cmd);

    // prime the timeout timer


    // buffer the response of the ELM327 until either the
    // end marker is read or a timeout has occurred
    /*
    while ((counter < (PAYLOAD_LEN_UART3 + 1)) && !checkTimeout(previousTime)) {
       Serial_println_s("Test2:");
        if (SerialUart3_available()) {
            Serial_println_s("Test3:");
            while(!SerialUart3_available())
            {
              delay(100);
            }
            char recChar = SerialUart3_read();
            Serial_println_s(recChar);

            if (recChar == '>')
                break;
            else if (isspace(recChar))
                continue;

            payloadUart3[counter] = recChar;
            counter++;
        }
    }
    */
    char response;
    //Serial_println_s("Test:");
    //Serial_println_u(SerialUart3_available());
    delay(100);
    while(!checkTimeout(previousTime)){
        response = SerialUart3_read();
        //Serial_println_s(response);
    }

    recBytes = counter;
    payloadUart3="test";
    return payloadUart3;
}

void prepateHTTP1()
{

    SerialUart3_println_s("AT+HTTPINIT");
    delay(100);
}

void prepateHTTP2()
{
    delay(1000);
    SerialUart3_println_s("AT+HTTPPARA=\"CID\",1");
    delay(100);

}

void terminateHttpConnection()
{

    SerialUart3_println_s("AT+HTTPINIT");
    delay(100);
}

void checkStandby() {
  uint8_t standby_pin = GPIO_ReadInputPin(GPIOB, GPIO_PIN_1);

  if (standby_pin >= 1) {
    carWasOnline = 1;
  }

  if (carWasOnline == 1)
  {
    if (standby_pin < 1)
    {
        if (standby == 1) {
          GPIO_WriteLow(GPIOA, GPIO_PIN_3);
        }

        if (standby_counter_start == 0 && standby == 0) {
          standby_counter_start = millis();
        }
        else {
          if (millis() - standby_counter_start >= 20000 && standby == 0)  {
            standby_counter_start = 0;
            standby = 1;
          }
        }
      }
      else
      {
        if (standby == 1) {
          GPIO_WriteHigh(GPIOA, GPIO_PIN_3);
          delay(2000);
          GPIO_WriteLow(GPIOG, GPIO_PIN_1);
          delay(1000);
          GPIO_WriteHigh(GPIOG, GPIO_PIN_1);
          delay(1000);
          standby = 0;

          initializeObdElm();
          initializeSim808();
        }
      }
  }
}
void prepareHttpEndpointUrl()
{
    char data_url[300] = "AT+HTTPPARA=\"URL\",\"http://37.251.139.87:5000/save\"";
    char json_para_header[300] = "AT+HTTPPARA=\"CONTENT\",\"application/json\"";

//    char *bufferSim808;
//
//    sim808_flush_serial();
//
//    //char float_result[10];
//
//    sim808_send_cmd("AT+CGPSINF=0");
//    sim808_read_buffer(bufferSim808, 32);

    //Serial_println_s(bufferSim808);
//    char* float_result = SIM808_sendCommand();
    //float obd_result = ELM327_rpm();

    // char* float_result = ELM327_rpm();
    //sprintf(float_result, "%d", (int)obd_result);

    //strcat(data_url, bufferSim808);
    //strcat(data_url, "\"");

    SerialUart3_println_s(data_url);
    SerialUart3_println_s(json_para_header);
    delay(100);
}

void prepareHTTPBody()  {
  char request_body[100] = "{\"rpm\":100,\"speed\":80,\"fuel\":60}";
  char data_command[40] = "AT+HTTPDATA=100,2000";

  delay(100);
  SerialUart3_println_s(data_command);
  delay(1500);
  SerialUart3_println_s(request_body);
  delay(200);
}

void executeGetRequest()
{
    SerialUart3_println_s("AT+HTTPACTION=0");
    delay(100);
}

void executePostRequest()
{
    SerialUart3_println_s("AT+HTTPACTION=1");
    delay(100);
}

// SIM808 End functions

void GPIO_setup(void)
{

    GPIO_DeInit(GPIOG);
    GPIO_Init(GPIOG, GPIO_PIN_1, GPIO_MODE_OUT_OD_LOW_SLOW);

    GPIO_DeInit(GPIOA);
    GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_FAST);

    GPIO_DeInit(GPIOB);
    GPIO_Init(GPIOB, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);
}
// te auzim
void loop() {
    if (standby == 0)
    {
      delay(100);
      prepateHTTP1();
      prepateHTTP2();
      prepareHttpEndpointUrl();
      prepareHTTPBody();

      delay(2000);
      executePostRequest();
      delay(3000);
      terminateHttpConnection();


      delay(500);
      ELM327_rpm();
    }
    delay(300);
    checkStandby();
}