#define _GNU_SOURCE
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>

static void ignore_sigchild(){};
typedef void (*sighandler_t)(int);


int run_cmd_and_get_output (char *cmd, int length, char **out_buffer, size_t *out_buffer_sz, size_t *out_buffer_max_size, int8_t grow_outbuffer)
{
#define OUT_BUFFER_DELTA_SZ 4096
  FILE *app = NULL;
  char *out_local_buffer = *out_buffer;

  // NSLBDL2_MISC("Method called. Command = %s", cmd);

  sighandler_t prev_handler;
  prev_handler = signal(SIGCHLD, ignore_sigchild);
  app = popen(cmd, "r");

  if(app == NULL)
  {
    fprintf(stderr, "Error: Error in executing command = %s. Error = %s\n", cmd, strerror(errno));
    return -1;
  }

  char line[OUT_BUFFER_DELTA_SZ + 1];
  int line_len;
  size_t amt_written = 0;

  while(fgets(line, OUT_BUFFER_DELTA_SZ, app))
  {
    line_len = strlen(line);

    // check if it does have space.
    if (amt_written + line_len + 1 > *out_buffer_max_size) {
       if (!grow_outbuffer) {
         // copy as much available and break.
         line_len = *out_buffer_max_size - amt_written - 1 /*for null char*/;

         if (line_len > 0)
         {
           memcpy(out_local_buffer + amt_written, line, line_len);
           amt_written += line_len;
         }
         break;
       }

       // realloc.
       out_local_buffer = realloc(out_local_buffer, *out_buffer_max_size + OUT_BUFFER_DELTA_SZ + 1);
       *out_buffer_max_size += OUT_BUFFER_DELTA_SZ + 1;
    }

    // copy then content
    memcpy(out_local_buffer + amt_written, line, line_len);
    amt_written += line_len;
  }

  out_local_buffer[amt_written] = 0;
  *out_buffer = out_local_buffer;
  *out_buffer_sz = amt_written;

  if(pclose(app) == -1)
  {
    // Changed the fprintf stderr to DBG log message; fix for bug#6742
    fprintf(stderr, "Error: Error in pclose() after executing following cmd: '%s', "
                    "This may happen due to child exiting before pclose(), "
                    "Hence ignoring. Error returned by system: '%s'",
                    cmd, strerror(errno));
  }
  (void) signal( SIGCHLD, prev_handler);

  return 0;
}

// TODO: need to handle argument. 
char *get_jwt_token(const char *jwt_token_param) {
	char *cmd = "node -e \"const data = fs.readFileSync('/home/cavisson/work/workspace/admin/system/cavisson/default/default/scripts/hpd_tours/crypto-js.min.js', {'encoding': 'utf8'}); eval(data);\"";
	
	char *output = malloc(4 * 1024);
	size_t out_buffer_sz; 
	size_t out_buffer_max_sz = 4 * 1024;
	// int rv = run_cmd_and_get_last_line(cmd, strlen(cmd), output); 
	int rv = run_cmd_and_get_output(cmd, strlen(cmd), &output, &out_buffer_sz, &out_buffer_max_sz, 0);

	if (rv != 0) {
          free(output);
          return NULL;
	}

	if (!strncasecmp(output, "JWT=", 4)) {
	  // If it's not eror then save value in given param. 
          ns_save_string(output + 4, jwt_token_param);
          free(output);
	} else {
          fprintf(stderr, "Invalid JWTToken - %s\n", output);
	  free(output);
	  return NULL;
	}

	char param[512];
	sprintf(param, "{%s}", jwt_token_param);
	return ns_eval_string(param);
}



