/*
 * Copyright 2001-2004 Brandon Long
 * All Rights Reserved.
 *
 * ClearSilver Templating System
 *
 * This code is made available under the terms of the ClearSilver License.
 * http://www.clearsilver.net/license.hdf
 *
 */

#include "cs_config.h"

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <dirent.h>
#include <sys/stat.h>

#include "neo_misc.h"
#include "neo_err.h"
#include "neo_files.h"
#include "wildmat.h"

NEOERR *ne_mkdirs (const char *path, mode_t mode)
{
  char mypath[_POSIX_PATH_MAX];
  int x;
  int r;

  strncpy (mypath, path, sizeof(mypath));
  x = strlen(mypath);
  if ((x < sizeof(mypath)) && (mypath[x-1] != '/'))
  {
    mypath[x] = '/';
    mypath[x+1] = '\0';
  }

  for (x = 1; mypath[x]; x++)
  {
    if (mypath[x] == '/')
    {
      mypath[x] = '\0';
#ifdef __MINGW32__
      /* Braindead MINGW32 doesn't just have a dummy argument for mode */
      r = mkdir (mypath);
#else
      r = mkdir (mypath, mode);
#endif

      if (r == -1 && errno != EEXIST)
      {
	return nerr_raise_errno(NERR_SYSTEM, "ne_mkdirs: mkdir(%s, %x) failed", mypath, mode);
      }
      mypath[x] = '/';
    }
  }
  return STATUS_OK;
}

NEOERR *ne_load_file_len (const char *path, char **str, int *out_len)
{
  struct stat s;
  int fd;
  int len;
  int bytes_read;

  *str = NULL;
  if (out_len) *out_len = 0;

  if (stat(path, &s) == -1)
  {
    if (errno == ENOENT)
      return nerr_raise (NERR_NOT_FOUND, "File %s not found", path);
    return nerr_raise_errno (NERR_SYSTEM, "Unable to stat file %s", path);
  }

  fd = open (path, O_RDONLY);
  if (fd == -1)
  {
    return nerr_raise_errno (NERR_SYSTEM, "Unable to open file %s", path);
  }
  len = s.st_size;
  *str = (char *) malloc (len + 1);

  if (*str == NULL)
  {
    close(fd);
    return nerr_raise (NERR_NOMEM, 
	"Unable to allocate memory (%d) to load file %s", len + 1, path);
  }
  if ((bytes_read = read (fd, *str, len)) == -1)
  {
    close(fd);
    free(*str);
    return nerr_raise_errno (NERR_SYSTEM, "Unable to read file %s", path);
  }

  (*str)[bytes_read] = '\0';
  close(fd);
  if (out_len) *out_len = bytes_read;

  return STATUS_OK;
}

NEOERR *ne_load_file (const char *path, char **str) {
  return ne_load_file_len (path, str, NULL);
}

NEOERR *ne_save_file (const char *path, char *str)
{
  NEOERR *err;
  int fd;
  int w, l;

  fd = open (path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
  if (fd == -1)
  {
    return nerr_raise_errno (NERR_IO, "Unable to create file %s", path);
  }
  l = strlen(str);
  w = write (fd, str, l);
  if (w != l)
  {
    err = nerr_raise_errno (NERR_IO, "Unable to write file %s", path);
    close (fd);
    return err;
  }
  close (fd);

  return STATUS_OK;
}

NEOERR *ne_remove_dir (const char *path)
{
  NEOERR *err;
  DIR *dp;
  struct stat s;
  struct dirent *de;
  char npath[_POSIX_PATH_MAX];

  if (stat(path, &s) == -1)
  {
    if (errno == ENOENT) return STATUS_OK;
    return nerr_raise_errno (NERR_SYSTEM, "Unable to stat file %s", path);
  }
  if (!S_ISDIR(s.st_mode))
  {
    return nerr_raise (NERR_ASSERT, "Path %s is not a directory", path);
  }
  dp = opendir(path);
  if (dp == NULL)
    return nerr_raise_errno (NERR_IO, "Unable to open directory %s", path);
  while ((de = readdir (dp)) != NULL)
  {
    if (strcmp(de->d_name, ".") && strcmp(de->d_name, ".."))
    {
      snprintf (npath, sizeof(npath), "%s/%s", path, de->d_name);
      if (stat(npath, &s) == -1)
      {
	if (errno == ENOENT) continue;
	closedir(dp);
	return nerr_raise_errno (NERR_SYSTEM, "Unable to stat file %s", npath);
      }
      if (S_ISDIR(s.st_mode))
      {
	err = ne_remove_dir(npath);
	if (err) break;
      }
      else
      {
	if (unlink(npath) == -1)
	{
	  if (errno == ENOENT) continue;
	  closedir(dp);
	  return nerr_raise_errno (NERR_SYSTEM, "Unable to unlink file %s", 
	      npath);
	}
      }
    }
  }
  closedir(dp);
  if (rmdir(path) == -1)
  {
    return nerr_raise_errno (NERR_SYSTEM, "Unable to rmdir %s", path);
  }
  return STATUS_OK;
}

NEOERR *ne_listdir(const char *path, ULIST **files)
{
  return nerr_pass(ne_listdir_fmatch(path, files, NULL, NULL));
}

static int _glob_match(void *rock, const char *filename)
{
  return wildmat(filename, rock);
}

NEOERR *ne_listdir_match(const char *path, ULIST **files, const char *match)
{
  return nerr_pass(ne_listdir_fmatch(path, files, _glob_match, (void *)match));
}

NEOERR *ne_listdir_fmatch(const char *path, ULIST **files, MATCH_FUNC fmatch, 
                          void *rock)
{
  DIR *dp;
  struct dirent *de;
  ULIST *myfiles = NULL;
  NEOERR *err = STATUS_OK;

  if (files == NULL) 
    return nerr_raise(NERR_ASSERT, "Invalid call to ne_listdir_fmatch");

  if (*files == NULL)
  {
    err = uListInit(&myfiles, 10, 0);
    if (err) return nerr_pass(err);
  }
  else
  {
    myfiles = *files;
  }

  if ((dp = opendir (path)) == NULL)
  {
    return nerr_raise_errno(NERR_IO, "Unable to opendir %s", path);
  }
  while ((de = readdir (dp)) != NULL)
  {
    if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
      continue;

    if (fmatch != NULL && !fmatch(rock, de->d_name))
      continue;

    err = uListAppend(myfiles, strdup(de->d_name));
    if (err) break;
  }
  closedir(dp);
  if (err && *files == NULL)
  {
    uListDestroy(&myfiles, ULIST_FREE);
  }
  else if (*files == NULL)
  {
    *files = myfiles;
  }
  return nerr_pass(err);
}
