#include <Arduino.h>

using namespace std;

#if DEBUG == 1
  #define debug(x) Serial.print(x)
  #define debugln(x) Serial.println(x)
#else
#define debug(x)
#define debugln(x)  
#endif

struct data {
    char result[10][50];
    int index;
    int location[10];
    byte size[10];
    char *temp;
    int upnext;
};


//struct data p[4] = {result[10][50], index, location[10], size[10], *temp, upnext}


  struct data p[4] = {};

//Template for array Dictionary
  const char parsedStrings[15][15] = {" "};





  /*
{
  key:
	{
    key:value,
	    key:value,
	      key:[value,value,value
        ]
	}
}
*/
  //key1
  // 0-0 = (set)
  // 0-1 = (get)
  // 0-2 = (clear)
  
  //key2
  // 1-0 = (function)
  // 1-1 = (wifi)
  // 1-2 = (ble"bluetooth")
  
  //value1
  // 3-0 = (#)
  
  //key3
  // 3-1 = (ssid,password,ip,hostname,gateway,dns)
  
  //value2
  // 4-0 = (on,off,fillall,bright,fade,effect,delay,rgb,saturation)
  
  //key4
  // 5-0 = (up,down,add,red,green,blue)

  //value4
  // 6-0 = (#)

  //value5
  // 7-0 = (#)

  //value6
  // 8-0 = (#)



void SetAction() {
  printf("Triggered: set\n");

  }
/////  

char* Parser(char* tempInput, char d, int* ndxptr, int* nxt) {
    // Stores the state of string
    static char* input = NULL;
    // Initialize the input string
    if (tempInput != NULL){
        debugln("tempInput");
        input = tempInput;
        }
    // Case for final token
    if (input == NULL) {
        debugln("input");
        return "\0";
      }
        // Stores the extracted string
        char* result = new char[strlen(input) + 1];
      int i = 0;
    
        // Start extracting string and
        // store it in array
        // If not at the end of the array
        // Keep looking through
      for (; input[i] != '\0'; i++) {
        // If current character is not
        // equal to the delimiting char
        // assign to result
        if ( input[i] != d ) {
          debugln("if");
          result[i] = input[i];
          *ndxptr = *ndxptr + 1;
          *nxt+= 1;
          }
        // Else store the string formed
        // and set t
        else {
          debugln("else");
          result[i] = '\0';
          debugln(input);
          // Moves the pointer of the first
          // char to the next delimiter + 1
          *ndxptr = *ndxptr + 1;
          *nxt = *nxt + 1;
          input = input + i + 1;
          debugln(input);
          return result;
        }
      }
      debugln("end");
      result[i] = '\0';
      input = NULL;
      return result;
    } 
/////

    //char result[10][50];  //  p[0].result[p[0].index]
    //int index;            //  p[0].index
    //int location[10];     //  p[0].location[p[0].index]
    //byte size[10];        //  p[0].size[p[0].index]
    //char *temp;           //  p[0].temp
    //int upnext;           //  p[0].upnext

void ReadSerial() {
  char userInput[75] = "";
    while(Serial.available() > 0) {
      size_t numChars = Serial.readBytesUntil('\n', userInput, sizeof(userInput) - 1);
      userInput[numChars] = '\0'; 
        printf("You entered: %s\n", userInput);
        printf("\n");
      int userInputSize = strlen(userInput);
        printf("Size of userInput = %i\n", userInputSize);
      int totalChars = userInputSize - 1;

  //------------------Colon
    printf("\n");
    printf("Delimiter = :\n");

    int ndxptr = 0;
    int nxt = 0;
    p[0].upnext = nxt;
    
    p[0].size[p[0].index];
    p[0].index = 0;
    
    p[0].temp = Parser(userInput, ':', &ndxptr, &nxt);
    p[0].upnext = nxt;
    p[0].size[p[0].index] = strlen(p[0].temp);
    p[0].location[p[10].index] = ndxptr;

      if (strlen(p[0].temp) > 0 && strlen(p[0].temp) < totalChars) {
        strcpy(p[0].result[p[0].index], p[0].temp);

        printf("Next delimiter = %d\n", p[0].upnext);
        printf("Current Delimiter = %d\n", p[0].location[p[0].index]);
        printf("\n");

        //printf("Colon: %i: %s\t Location: %d\n",p[0].index, p[0].result[p[0].index], p[0].location[p[0].index]);
        p[0].index++;
      }
    while(p[0].temp != "\0") {
    p[0].temp = Parser(NULL, ':', &ndxptr, &nxt);
      p[0].upnext = nxt;  
      p[0].size[p[0].index] = strlen(p[0].temp);
      p[0].location[p[0].index] = ndxptr;

        if (strlen(p[0].temp) > 0 && strlen(p[0].temp) < totalChars) {
          strcpy(p[0].result[p[0].index], p[0].temp);

          printf("Next delimiter = %d\n", p[0].upnext);
          printf("Current Delimiter = %d\n", p[0].location[p[0].index]);
          printf("\n");

          //printf("Colon: %i: %s\t Location: %d\n",p[0].index, p[0].result[p[0].index], p[0].location[p[0].index]);
          p[0].index++;
          }
        } 
      //Reove the [ from [function or whatever input is  so you just have the key
      if(p[0].result[1][0] == '[') {
          strcpy(p[0].result[1], &p[0].result[1][1]);
        }

  //------------------Comma
  
    printf("\n");
    printf("Delimiter = ,\n");
    nxt = 0;
    ndxptr = 0;

    p[1].temp = Parser(userInput, ',', &ndxptr, &nxt); 
      p[1].upnext = nxt; 
      p[1].size[p[1].index] = strlen(p[1].temp);
      p[1].location[p[1].index] = ndxptr;
      
    if (strlen(p[1].temp) > 0 && strlen(p[1].temp) < totalChars) {
      strcpy(p[1].result[p[1].index], p[1].temp);

      printf("Next delimiter = %d\n", p[1].upnext);
      printf("Current Delimiter = %d\n", p[1].location[p[1].index]);
      printf("\n");

      //printf("Comma %i: %s\t Location: %d\n",p[1].index, p[1].result[p[1].index], p[1].location[p[1].index]);  
      p[1].index++;  
      }

    while(p[1].temp != "\0") {
      p[1].temp = Parser(NULL, ',', &ndxptr, &nxt);
      p[1].upnext = nxt;
      p[1].size[p[1].index] = strlen(p[1].temp);
      p[1].location[p[1].index] = ndxptr;

    if (strlen(p[1].temp) > 0 && strlen(p[1].temp) < totalChars) {
      strcpy(p[1].result[p[1].index], p[1].temp);

      printf("Next delimiter = %d\n", p[1].upnext);
      printf("Current Delimiter = %d\n", p[1].location[p[1].index]);
      printf("\n");

      //printf("Comma %i: %s\t Location: %d\n",p[1].index, p[1].result[p[1].index], p[1].location[p[1].index]);
      p[1].index++;  
        }
      }
  
  //------------------Left Bracket    
  
    printf("\n");
    printf("Delimiter = [\n");
    ndxptr = 0;
    nxt = 0;

    p[2].temp = Parser(userInput, '[', &ndxptr, &nxt);
      p[2].upnext = nxt;  
      p[2].size[p[2].index] = strlen(p[2].temp);
      p[2].location[p[2].index] = ndxptr;

    if (strlen(p[2].temp) > 0 && strlen(p[2].temp) < totalChars) {
      strcpy(p[2].result[p[2].index], p[2].temp);

      printf("Next delimiter = %d\n", p[2].upnext);
      printf("Current Delimiter = %d\n", p[2].location[p[2].index]);
      printf("\n");

      //printf("Left Bracket %i: %s\t Location: %d\n", p[2].index, p[2].result[p[2].index], p[2].location[p[2].index]);  
      p[2].index++;
      } 
      
    while(p[2].temp != "\0") {
      p[2].temp = Parser(NULL, '[', &ndxptr, &nxt);
      p[2].upnext  = nxt;
      p[2].size[p[2].index] = strlen(p[2].temp);  
      p[2].location[p[2].index] = ndxptr;

      if(strlen(p[2].temp) > 0 && strlen(p[2].temp) < totalChars) {
        strcpy(p[2].result[p[2].index], p[2].temp);

        printf("Next delimiter = %d\n", p[2].upnext );
        printf("Current Delimiter = %d\n", p[2].location[p[2].index]);
        printf("\n");

        //printf("Left Bracket %i: %s\t Location: %d\n", p[2].index, p[2].result[p[2].index], p[2].location[p[2].index]);
        p[2].index++;
        }
      }

  //------------------Right Bracket
  
    printf("\n");
    printf("Delimiter = ]\n");
    int rbr = 0;
    byte rbrSize[10];
    int rbrLocation[10];
    ndxptr = 0;
    nxt = 0;

    p[3].temp = Parser(userInput, ']', &ndxptr, &nxt);
      p[3].upnext = nxt;
      p[3].size[p[3].index] = strlen(p[3].temp);
      p[3].location[rbr] = ndxptr;

    if (strlen(p[3].temp) > 0 && strlen(p[3].temp) < totalChars) {
      strcpy(p[3].result[p[3].index], p[3].temp);

      printf("Next delimiter = %d\n", p[3].upnext);
      printf("Current Delimiter = %d\n", p[3].location[p[3].index]);
      printf("\n");

      //printf("Right Bracket #%i is %s and located at %d\n", p[3].index, p[3].result[p[3].index], p[3].location[p[3].index]);
      p[3].index++;
      } 

    while(p[3].temp != "\0") {
      p[3].temp = Parser(NULL, ']', &ndxptr, &nxt);
      p[3].upnext = nxt;
      p[3].size[p[3].index] = strlen(p[3].temp);
      p[3].location[p[3].index] = ndxptr;

    if(strlen(p[3].temp) > 0 && strlen(p[3].temp) < totalChars) {
      strcpy(p[3].result[p[3].index], p[3].temp);

      printf("Next delimiter = %d\n", p[3].upnext);
      printf("Current Delimiter = %d\n", p[3].location[p[3].index]);
      printf("\n");

      //printf("Right Bracket #%i is %s and located at %d\n", p[3].index, p[3].result[p[3].index], p[3].location[p[3].index]);
      p[3].index++;
      }
    else if(userInput[userInputSize] == ']') {
      printf("Right Bracket #%i is %s and located at %d\n", p[3].index, p[3].result[p[3].index], p[3].location[p[3].index]);
      }
    }
  
      }
////      
    printf("Outcome of p[0].result[1] after removal of [ = %s\n",p[0].result[1]);


    if(strncmp(p[0].result[0], "set", int(3)) == 0) {
      printf("Triggered: set\n");
      }
    else if ( strncmp ( p[0].result[0], "get", int(3)) == 0) {
      printf("Triggered: get\n");
    }

    }

/////

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Hello, ESP32!");

}

void loop() {
  // put your main code here, to run repeatedly:
  delay(10); // this speeds up the simulation
  
if(Serial.available() > 0) {
    ReadSerial();
  }

}