#include <string.h>
#include <stdarg.h>
#ifdef LINUX
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#endif

#include "lephisto.h"
#include "log.h"
#include "lfile.h"

/* Return lephisto's base path. */
static char lephisto_base[128] = "\0";
char* lfile_basePath(void) {
  char* home;

  if(lephisto_base[0] == '\0') {
#ifdef LINUX
    home = getenv("HOME");
#else
#error "Needs implentation."
#endif
    snprintf(lephisto_base, PATH_MAX, "%s/.lephisto/", home);
  }

  return lephisto_base;
}

/* Check if a directory exists, and create it if it doesn't. */
/* Based on lephisto_base. */
int lfile_dirMakeExist(const char* path) {
  char file[PATH_MAX];

#ifdef LINUX
  struct stat buf;

  if(strcmp(path, ".")==0) {
    strncpy(file, lfile_basePath(), PATH_MAX);
    file[PATH_MAX-1] = '\0';
  }
  else
    snprintf(file, PATH_MAX, "%s%s", lfile_basePath(), path);
  stat(file, &buf);
  if(!S_ISDIR(buf.st_mode))
    if(mkdir(file, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
      WARN("Dir '%s' does not exist and unable to create", path);
      return -1;
    }
#else
#error "Needs implentation."
#endif

  return 0;
}

/* Check if a file exists. */
int lfile_fileExists(const char* path, ...) {
  char file[PATH_MAX], name[PATH_MAX];
  va_list ap;
  size_t l;

  l = 0;
  if(path == NULL) return -1;
  else { /* Get the message. */
    va_start(ap, path);
    vsnprintf(name, PATH_MAX-l, path, ap);
    l = strlen(name);
    va_end(ap);
  }

  snprintf(file, PATH_MAX, "%s%s", lfile_basePath(), name);
#ifdef LINUX
  struct stat buf;

  if(stat(file, &buf)==0) /* Stat worked, file must exist. */
    return 1;
#else
#error "Needs implementation."
#endif
  return 0;
}

/* List all the files in a dir (besides . and ..). */
char** lfile_readDir(int* lfiles, const char* path) {
  char file[PATH_MAX];
  char** files;

  snprintf(file, PATH_MAX, "%s%s", lfile_basePath(), path);

#ifdef LINUX
  DIR* d;
  struct dirent *dir;
  char* name;
  int mfiles;

  (*lfiles) = 0;
  mfiles = 100;
  files = malloc(sizeof(char*)*mfiles);

  d = opendir(file);
  if(d == NULL) {
    return NULL;
  }

  while((dir = readdir(d)) != NULL) {
    name = dir->d_name;

    if((strcmp(name, ".")==0) || (strcmp(name, "..")==0))
      continue;

    if((*lfiles)+1 > mfiles) {
      mfiles += 100;
      files = realloc(files, sizeof(char*) * mfiles);
    }

    files[(*lfiles)] = strdup(name);
    (*lfiles)++;
  }

  closedir(d);
#else
#error "Needs implementation."
#endif

  /* What if we find nothing? */
  if((*lfiles) == 0) {
    free(files);
    files = NULL;
  }

  return files;
}

