#include "./meshtalos.h"
#include "log.h"
#include <mpack.h>
#include <stdio.h>
#include <sys/stat.h>

#define BUF_LEN 512
#define MAX_NAME_LEN 50
const char BUF[BUF_LEN] = {0};

struct Storage *storage_init() {
  FILE *list_peers = fopen("listp", "w+");
  if (list_peers == NULL) {
    log_fatal("Failed to open listp");
    return NULL;
  }
  struct Storage *storage = calloc(1, sizeof(struct Storage));
  if (storage == NULL) {
    log_fatal("Failed to allocate memory");
    goto err_ret;
  }
  struct stat st;
  if (fstat(fileno(list_peers), &st) == 0) {
    log_fatal("failed to get size");
    goto err_ret;
  }
  char *pids = calloc(sizeof(char), st.st_size);
  if (pids == NULL) {
    goto err_ret;
  }
  storage->peerids = pids;
  if (fgets(pids, st.st_size, list_peers) == NULL) {
    log_fatal("failed to read");
    goto err_ret;
  }
  for (char *name = pids; name <= &pids[st.st_size - 1];
       name += strlen(name) + 1) {
    // TODO read peer
  }

  return storage;

err_ret:
  if (list_peers)
    fclose(list_peers);
  if (storage) {
    if (storage->peerids) {
      free(storage->peerids);
    }
    // free_peers
    free(storage);
  }
  return NULL;
}

struct Peer *storage_read_peer(struct Storage *st, const char *pid) {
  char filename[PEER_ID_LEN + 2] = {'p', '\0'};
  strcat(filename, pid);
  FILE *fpeer = fopen(filename, "r");
  if (fpeer == NULL) {
    return NULL;
  }
  struct Peer *p = calloc(1, sizeof(struct Peer));
  int peer_len = fread(BUF, 1, BUF_LEN, fpeer);
  if (peer_len != BUF_LEN && !feof(fpeer))
    goto err_ret;
  mpack_tree_t tree;
  mpack_tree_init_data(&tree, BUF, peer_len);
  mpack_node_t root = mpack_tree_root(&tree);

  if (p == NULL) {
    goto err_ret;
  }

  p->peer_name =
      mpack_node_cstr_alloc(mpack_node_array_at(root, 0), MAX_NAME_LEN);
  p->last_online = mpack_node_u64(mpack_node_array_at(root, 1));
  p->tags = mpack_node_u8(mpack_node_array_at(root, 2));

err_ret:
  if (fpeer != NULL) {
    fclose(fpeer);
  }
  if (p) {
    if (p->peer_name) {
      free(p->peer_name);
    }
    free(p);
  }
  return NULL;
}
