/*
* main function to handle Parse GET/CREATE/DELETE/UPDATE/QUERY request
* @params
* -v - http verb
* -e - http endpoint
* -d - request body
* -p - parameters (used only for Parse query)
* -i - command to get installation id
*/
int main(int argc , char **argv) {
  char c;
  extern char* optarg;

  yunReadProvisioningInfo();

  ParseClient client = parseInitialize(g_cAppID,g_cClientKey);

  if(g_cInstallationID[0] != '\0') {
	parseSetInstallationId(client, g_cInstallationID);
  }
  if(g_cSessionToken[0] != '\0') {
	parseSetSessionToken(client, g_cSessionToken);
  }

  while((c=getopt(argc,argv,"v:e:d:p:is"))!=-1){
    switch(c){
      case 'v': // http verb
      if(!(verb=strdup(optarg))){
        return -1;
      }
      break;
      case 'e': // http endpoint
      if(!(endpoint=strdup(optarg))){
        return -1;
      }
      break;
      case 'd': // request body
      if(!(data=strdup(optarg))){
      }
      fprintf(stderr, "data = '%s'\n", data);
      break;
      case 'p': // parameters
      if(!(params=strdup(optarg))){
      }
      break;
      case 'i':
      arduinoGetInstallationId(client);
      exit(0);
      case 's':
      arduinoGetSessionToken(client);
      exit(0);
    }
  }

  if (strncmp("GET", verb, 3) == 0) {
    data = params;
  }

  if (client) {
    if (!params) {
      parseSendRequest(client, verb, endpoint, data, arduinoCallHandler);
    } else {
      parseSendRequest(client, verb, endpoint, params, arduinoQueryHandler);
    }
  }

  exit(0);
}
ParseClient parseInitializeWithServerURL(
        const char *applicationId,
        const char *clientKey,
        const char *serverURL)
{
    parseSetLogLevel(PARSE_LOG_WARN);

    ParseClientInternal *client = calloc(1, sizeof(ParseClientInternal));
    if (client == NULL) {
        parseLog(PARSE_LOG_ERROR, "%s:%s generated out of memory.\n", __FUNCTION__, __LINE__);
        return NULL;
    }
    if (applicationId != NULL)
        client->applicationId= strdup(applicationId);
    if (clientKey != NULL)
        client->clientKey = strdup(clientKey);

    if (serverURL != NULL)
        client->serverURL = strdup(serverURL);
    else if (serverURL == NULL)
        client->serverURL = strdup(PARSE_DEFAULT_SERVER_URL);

    char version[256];
    parseOsGetVersion(version, sizeof(version));
    client->osVersion = strdup(version);

    char temp[40];
    parseOsLoadKey(client->applicationId, PARSE_INSTALLATION_ID, temp, sizeof(temp));
    if (temp[0] != '\0') {
        parseSetInstallationId((ParseClient)client, temp);
    }

    parseOsLoadKey(client->applicationId, PARSE_SESSION_TOKEN, temp, sizeof(temp));
    if (temp[0] != '\0') {
        parseSetSessionToken((ParseClient)client, temp);
    }

    parseOsLoadKey(client->applicationId, PARSE_LAST_PUSH_TIME, temp, sizeof(temp));
    if (temp[0] != '\0') {
        client->lastPushTime = strdup(temp);
    }

    curl_global_init(CURL_GLOBAL_ALL);

    return (ParseClient)client;
}
int main(int argc , char **argv) {
  char c;

  int isYun = yunReadProvisioningInfo();

  // process pre init options
  while((c=getopt(argc,argv,":a:k:x:y:v:e:d:p:ish"))!=-1){
    switch(c) {
        case 'h':
            displayHelp();
            exit(0);
        case 'a':
            strncpy(g_cAppID, optarg, sizeof(g_cAppID));
            break;
        case 'k':
            strncpy(g_cClientKey, optarg, sizeof(g_cClientKey));
            break;
        case 'x':
            strncpy(g_cInstallationID, optarg, sizeof(g_cInstallationID));
            break;
        case 'y':
            strncpy(g_cSessionToken, optarg, sizeof(g_cSessionToken));
            break;
        case 'v':
        case 'e':
        case 'd':
        case 'p':
        case 'i':
        case 's':
            // these we want to process later
            break;
        case ':':
          fprintf(stderr, "%s: option '-%c' requires an argument\n", argv[0], optopt);
          exit(0);
        case '?':
          fprintf(stderr, "%s: option '-%c' is not recognized \n", argv[0], optopt);
          exit(0);
        default:
          fprintf(stderr, "%s: option '-%c' is not implemented\n", argv[0], optopt);
          exit(0);
    }
  }

  if (g_cAppID[0] == '\0') {
    fprintf(stdout, "{\"error\":\"missing application id\"}\n");
    exit(0);
  }
  if (g_cClientKey[0] == '\0') {
    fprintf(stdout, "{\"error\":\"missing client key\"}\n");
    exit(0);
  }

  ParseClient client = parseInitialize(g_cAppID,g_cClientKey);

  if(g_cInstallationID[0] != '\0') {
	parseSetInstallationId(client, g_cInstallationID);
  }
  if(g_cSessionToken[0] != '\0') {
	parseSetSessionToken(client, g_cSessionToken);
  }

  // process post init options
  optreset = 1;
  optind = 1;

  while((c=getopt(argc,argv,":a:k:x:y:v:e:d:p:ish"))!=-1){
    switch(c){
      case 'v': // http verb
        if(!(verb=strdup(optarg))){
            return -1;
        }
        break;
      case 'e': // http endpoint
        if(!(endpoint=strdup(optarg))){
            return -1;
        }
        break;
      case 'd': // request body
        if(!(data=strdup(optarg))){
        }
        break;
      case 'p': // parameters
        if(!(params=strdup(optarg))){
        }
        break;
      case 'i':
        arduinoGetInstallationId(client);
        exit(0);
      case 's':
        arduinoGetSessionToken(client);
        exit(0);
    }
  }

  if (strncmp("GET", verb, 3) == 0) {
    data = params;
  }

  if (client) {
    if (!params) {
      parseSendRequest(client, verb, endpoint, data, arduinoCallHandler);
    } else {
      parseSendRequest(client, verb, endpoint, params, arduinoQueryHandler);
    }
  }

  exit(0);
}
void parseClearSessionToken(ParseClient client)
{
    parseSetSessionToken(client, NULL);
}