#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "libb64/cencode.h"
#include "libb64/cdecode.h"
#include "util.h"

extern void sha512_compress(uint64_t state[8], const uint8_t block[128]);
extern int logfd;

char* strip(char* input, size_t sz) {
  char* clean = malloc(sz);
  int i = 0;
  while (*input) {
    if (*input == '\n') { input++; }
    if (!(strncmp(input, "�", 3))) { input += 3; }
    *clean = *input;
    clean++; input++; i++;
  }

  input -= i; 
  return (clean-i);
}

//Libb64 interface functions
void b64encode(char* input, char* output, size_t sz) {
  base64_encodestate s;
  char* clean;
  char* c = output;
  int cnt = 0;
  
  base64_init_encodestate(&s);
  cnt = base64_encode_block(input, strlen(input), c, &s);
  c += cnt;
  cnt = base64_encode_blockend(c, &s);
  c += cnt;
  *c = '\0';

  clean = strip(output, b64max(sz));
  snprintf(output, sz, "%s", clean);
  
#if DO_FREE
  free(clean);
#endif
}

void b64decode(char* input, char* output, size_t sz) {
  char* c = output;
  int cnt = 0;
  base64_decodestate s;

  base64_init_decodestate(&s);
  cnt = base64_decode_block(input, strlen(input), c, &s);
  c += cnt;
  *c = 0;
}
//End libb64 interface functions

char* read_file(char* path, size_t sz, size_t nmemb) {
  if ((sz*nmemb) > MAXLEN_FILE) { return NULL; }
  if (access(path, F_OK) == -1) { return NULL; }
  FILE* fp = fopen(path, "r");
  if (!fp) { return NULL; }
  char* buf = malloc(MAXLEN_FILE); memset(buf, 0, MAXLEN_FILE);
  if (!buf) { return NULL; }
  fread(buf, sz, nmemb, fp);
  if (ferror(fp)) { return NULL; }
  return buf;
}

void logs(char* msg, ...) {
  va_list ap;
  char buf[MAXLEN_LOG]; memset(buf, 0, MAXLEN_LOG);
  
  va_start(ap, msg);
  vsprintf(buf, msg, ap);
  va_end(ap);

  if (getenv("DEBUG")) {
    printf("%s\n", buf);
  }
  
  write(logfd, buf, MAXLEN_LOG);
  write(logfd, "\n", 1);
}

