
#include <string.h>
#include "../native-common/base64.h"
#include "appborg.h"

// TODO: memory leaks
// TODO: (long long) ids
// TODO: full error handling

#define APPBORG_LINEMAX 75000


ABComm *appborg_init(char *name) {
  ABComm *comm = calloc(1, sizeof(ABComm));
  comm->name = name;
  comm->counter = 0;
  return comm;
}


void appborg_free(ABComm *comm) {
  free(comm);
}


json_t* appborg_readEventSync(ABComm *comm) {
  
  // json64
  char line[APPBORG_LINEMAX + 1];
  if ( ! fgets(line, APPBORG_LINEMAX, stdin)) {
    return NULL;
  }
  line[strlen(line) - 1] = 0;// drop the \n
  
  // json
  int json_length;
  char* json = (char*)base64_decode(line, &json_length);
  json[json_length] = 0;
  
  // event
  json_error_t error;
  json_t *event = json_loads(json, 0, &error);
  // TODO validate error
  // TODO validate types
  // json_is_string
  
  return event;
}


void appborg_send(ABComm *comm, char *method, json_t *info, char *to) {
  comm->counter++;
  json_t *event = json_pack("{sssosissss}",
    "method", method,
    "info", info,
    "id", comm->counter,
    "from", comm->name,
    "to", to
  );
  appborg_writeEvent_(comm, event);
}


void appborg_respond(ABComm *comm, json_t *event, json_t *info) {
  appborg_respond_(comm, event, info, json_null());
}


void appborg_respondError(ABComm *comm, json_t *event, json_t *info) {
  appborg_respond_(comm, event, json_null(), info);
}


void appborg_fatalError_(ABComm *comm, char *msg) {
  fprintf(stderr, "[ABComm][FATALERROR] %s\n", msg);
  exit(1);
}


void appborg_respond_(ABComm *comm, json_t *event, json_t *result, json_t *error) {
  json_t *response = json_pack("{sososososo}",
    "result", result,
    "error",  error,
    "id",     json_object_get(event, "id"),
    "from",   json_object_get(event, "to"),
    "to",     json_object_get(event, "from")
  );
  appborg_writeEvent_(comm, response);
}


void appborg_writeEvent_(ABComm *comm, json_t *event) {
  char *json = json_dumps(event, JSON_COMPACT | JSON_ENSURE_ASCII | JSON_SORT_KEYS);
  char *json64 = base64_encode((unsigned char*)json, (int)strlen(json));
  fprintf(stdout, "%s\n", json64);
  fflush(stdout);
  free(json);
  free(json64);
}
