/**
 * This file is part of the mingw-w64 runtime package.
 * No warranty is given; refer to the file DISCLAIMER within this package.
 */

#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <dirent.h>
#include <ftw.h>

int __cdecl stat32(const char *_Filename, struct _stat32 *_Stat);
int __cdecl stat32i64(const char *_Filename, struct _stat32i64 *_Stat);
int __cdecl stat64i32(const char *_Filename, struct _stat64i32 *_Stat);

typedef struct dir_data_t {
  DIR *h;
  char *buf;
} dir_data_t;

typedef struct node_t {
  struct node_t *l, *r;
  unsigned int colored : 1;
} node_t;

typedef struct ctx_t {
  node_t *objs;
  dir_data_t **dirs;
  char *buf;
  struct FTW ftw;
  int (*fcb) (const char *, const STRUCT_STAT *, int , struct FTW *);
  size_t cur_dir, msz_dir, buf_sz;
  int flags;
  dev_t dev;
} ctx_t;

static int add_object (ctx_t *);
static int do_dir (ctx_t *, STRUCT_STAT *, dir_data_t *);
static int do_entity (ctx_t *, dir_data_t *, const char *, size_t);
static int do_it (const char *, int, void *, int, int);

static int open_directory (ctx_t *, dir_data_t *);

static void
prepare_for_insert (int forced, node_t **bp, node_t **pp1, node_t **pp2, int p1_c, int p2_c)
{
  node_t *p1, *p2, **rp, **lp, *b = *bp;

  rp = &(*bp)->r;
  lp = &(*bp)->l;

  if (!forced && ((*lp) == NULL || (*lp)->colored == 0 || (*rp) == NULL || (*rp)->colored == 0))
    return;

  b->colored = 1;

  if (*rp)
    (*rp)->colored = 0;

  if (*lp)
    (*lp)->colored = 0;

  if (!pp1 || (*pp1)->colored == 0)
    return;

  p1 = *pp1;
  p2 = *pp2;

  if ((p1_c > 0) == (p2_c > 0))
    {
      *pp2 = *pp1;
      p1->colored = 0;
      p2->colored = 1;
      *(p1_c < 0 ? &p2->l : &p2->r) = (p1_c < 0 ? p1->r : p1->l);
      *(p1_c < 0 ? &p1->r : &p1->l) = p2;
      return;
    }

  b->colored = 0;
  p1->colored = p2->colored = 1;
  *(p1_c < 0 ? &p1->l : &p1->r) = (p1_c < 0 ? *rp : *lp);
  *(p1_c < 0 ? rp : lp) = p1;
  *(p1_c < 0 ? &p2->r : &p2->l) = (p1_c < 0 ? *lp : *rp);
  *(p1_c < 0 ? lp : rp) = p2;
  *pp2 = b;
}

static int
add_object (ctx_t *ctx)
{
  node_t **bp, **np, *b, *n, **pp1 = NULL, **pp2 = NULL;
  int c = 0, p1_c = 0, p2_c = 0;

  if (ctx->objs)
    ctx->objs->colored = 0;

  np = bp = &ctx->objs;

  if (ctx->objs != NULL)
    {
      c = 1;

      do
	{
	  b = *bp;
	  prepare_for_insert (0, bp, pp1, pp2, p1_c, p2_c);
	  np = &b->r;

	  if (*np == NULL)
	    break;

	  pp2 = pp1;
	  p2_c = p1_c;
	  pp1 = bp;
	  p1_c = 1;
	  bp = np;
	}
      while (*np != NULL);
    }

  if (!(n = (node_t *) malloc (sizeof (node_t))))
    return -1;

  *np = n;
  n->l = n->r = NULL;
  n->colored = 1;

  if (np != bp)
    prepare_for_insert (1, np, bp, pp1, c, p1_c);

  return 0;
}

static int
open_directory (ctx_t *ctx, dir_data_t *dirp)
{
  DIR *st;
  struct dirent *d;
  char *buf, *h;
  size_t cur_sz, buf_sz, sz;
  int sv_e, ret = 0;

  if (ctx->dirs[ctx->cur_dir] != NULL)
    {
      if (!(buf = malloc (1024)))
	return -1;

      st = ctx->dirs[ctx->cur_dir]->h;

      buf_sz = 1024;
      cur_sz = 0;

      while ((d = readdir (st)) != NULL)
	{
	  sz = strlen (d->d_name);

	  if ((cur_sz + sz + 2) >= buf_sz)
	    {
	      buf_sz += ((2 * sz) < 1024 ? 1024 : (2 * sz));
	      if (!(h = (char *) realloc (buf, buf_sz)))
		{
		  sv_e = errno;
		  free (buf);
		  errno =  (sv_e);

		  return -1;
		}

	      buf = h;
	    }

	  *((char *) memcpy (buf + cur_sz, d->d_name, sz) + sz) = 0;
	  cur_sz += sz + 1;
	}

      buf[cur_sz++] = 0;

      ctx->dirs[ctx->cur_dir]->buf = realloc (buf, cur_sz);

      if (ctx->dirs[ctx->cur_dir]->buf == NULL)
	{
	  sv_e = errno;
	  free (buf);
	  errno = sv_e;
	  ret = -1;
	}
      else
	{
	  closedir (st);

	  ctx->dirs[ctx->cur_dir]->h = NULL;
	  ctx->dirs[ctx->cur_dir] = NULL;
	}
    }

  if (!ret)
    {
      dirp->h = opendir (ctx->buf);

      if (dirp->h == NULL)
	ret = -1;
      else
	{
	  dirp->buf = NULL;
	  ctx->dirs[ctx->cur_dir] = dirp;
	  ctx->cur_dir += 1;

	  if (ctx->cur_dir == ctx->msz_dir)
	    ctx->cur_dir = 0;
	}
    }

  return ret;
}


static int
do_entity (ctx_t *ctx, dir_data_t *dir, const char *name, size_t namlen)
{
  STRUCT_STAT st;
  char *h;
  size_t cnt_sz;
  int ret = 0, flag = 0;

  if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
    return 0;

  cnt_sz = ctx->ftw.base + namlen + 2;

  if (ctx->buf_sz < cnt_sz)
    {
      ctx->buf_sz = cnt_sz * 2;
      
      if (!(h = (char *) realloc (ctx->buf, ctx->buf_sz)))
	return -1;

      ctx->buf = h;
    }

  *((char *) memcpy (ctx->buf + ctx->ftw.base, name, namlen) + namlen) = 0;

  name = ctx->buf;

  if (FUNC_STAT (name, &st) < 0)
    {
      if (errno != EACCES && errno != ENOENT)
	ret = -1;
      else
	flag = FTW_NS;

      if (!(ctx->flags & FTW_PHYS))
	FUNC_STAT (name, &st);
    }
  else
    flag = (S_ISDIR (st.st_mode) ? FTW_D : FTW_F);

  if (!ret && (flag == FTW_NS || !(ctx->flags & FTW_MOUNT) || st.st_dev == ctx->dev))
    {
      if (flag == FTW_D)
	{
	  if ((ctx->flags & FTW_PHYS) || !(ret = add_object (ctx)))
	    ret = do_dir (ctx, &st, dir);
	}
      else
	ret = (*ctx->fcb) (ctx->buf, &st, flag, &ctx->ftw);
    }

  if ((ctx->flags & FTW_ACTIONRETVAL) && ret == FTW_SKIP_SUBTREE)
    ret = 0;

  return ret;
}


static int
do_dir (ctx_t *ctx, STRUCT_STAT *st, __UNUSED_PARAM(dir_data_t *old_dir))
{
  dir_data_t dir;
  struct dirent *d;
  char *startp, *runp, *endp;
  int sv_e, ret, previous_base = ctx->ftw.base;

  if ((ret = open_directory (ctx, &dir)) != 0)
    {
      if (errno == EACCES)
	ret = (*ctx->fcb) (ctx->buf, st, FTW_DNR, &ctx->ftw);

      return ret;
    }

  if (!(ctx->flags & FTW_DEPTH) && (ret = (*ctx->fcb) (ctx->buf, st, FTW_D, &ctx->ftw)) != 0)
    {
      sv_e = errno;
      closedir (dir.h);
      errno = sv_e;

      if (ctx->cur_dir-- == 0)
	ctx->cur_dir = ctx->msz_dir - 1;

      ctx->dirs[ctx->cur_dir] = NULL;

      return ret;
    }

  ctx->ftw.level += 1;
  startp = memchr (ctx->buf, 0, 1024);

  if (startp[-1] != '/')
    *startp++ = '/';

  ctx->ftw.base = (startp - ctx->buf);

  while (dir.h != NULL && (d = readdir (dir.h)) != NULL
         && !(ret = do_entity (ctx, &dir, d->d_name, strlen (d->d_name))))
      ;

  if (dir.h != NULL)
    {
      sv_e = errno;
      closedir (dir.h);
      errno = sv_e;

      if (ctx->cur_dir-- == 0)
	ctx->cur_dir = ctx->msz_dir - 1;

      ctx->dirs[ctx->cur_dir] = NULL;
    }
  else
    {
      runp = dir.buf;

      while (!ret && *runp != 0)
	{
	  endp = strchr (runp, 0);
	  ret = do_entity (ctx, &dir, runp, endp - runp);
	  runp = endp + 1;
	}

      sv_e = errno;
      free (dir.buf);
      errno = sv_e;
    }

  if ((ctx->flags & FTW_ACTIONRETVAL) && ret == FTW_SKIP_SIBLINGS)
    ret = 0;

  ctx->buf[ctx->ftw.base - 1] = 0;
  ctx->ftw.level -= 1;
  ctx->ftw.base = previous_base;

  if (!ret && (ctx->flags & FTW_DEPTH))
    ret = (*ctx->fcb) (ctx->buf, st, FTW_DP, &ctx->ftw);

  return ret;
}

static void
free_objs (node_t *r)
{
  if (r->l)
    free_objs (r->l);

  if (r->r)
    free_objs (r->r);

  free (r);
}

static int
do_it (const char *dir, __UNUSED_PARAM(int is_nftw), void *fcb, int descriptors, int flags)
{
  struct ctx_t ctx;
  STRUCT_STAT st;
  int ret = 0;
  int sv_e;
  char *cp;

  if (dir[0] == 0)
  {
    errno =  (ENOENT);
    return -1;
  }

  ctx.msz_dir = descriptors < 1 ? 1 : descriptors;
  ctx.cur_dir = 0;
  ctx.dirs = (dir_data_t **) alloca (ctx.msz_dir * sizeof (dir_data_t *));
  memset (ctx.dirs, 0, ctx.msz_dir * sizeof (dir_data_t *));

  ctx.buf_sz = 2 * strlen (dir);

  if (ctx.buf_sz <= 1024)
    ctx.buf_sz = 1024;

  ctx.buf = (char *) malloc (ctx.buf_sz);

  if (ctx.buf == NULL)
    return -1;

  cp = strcpy (ctx.buf, dir) + strlen (dir);

  while (cp > (ctx.buf + 1) && cp[-1] == '/')
    --cp;

  *cp = 0;

  while (cp > ctx.buf && cp[-1] != '/')
    --cp;

  ctx.ftw.level = 0;
  ctx.ftw.base = cp - ctx.buf;
  ctx.flags = flags;
  ctx.fcb = (int (*) (const char *, const STRUCT_STAT *, int , struct FTW *)) fcb;
  ctx.objs = NULL;

  if (!ret)
    {
      if (FUNC_STAT (ctx.buf, &st) < 0)
	ret = -1;
      else if (S_ISDIR (st.st_mode))
	{
	  ctx.dev = st.st_dev;

	  if (!(flags & FTW_PHYS))
	    ret = add_object (&ctx);

	  if (!ret)
	    ret = do_dir (&ctx, &st, NULL);
	}
      else
	ret = (*ctx.fcb) (ctx.buf, &st, FTW_F, &ctx.ftw);

      if ((flags & FTW_ACTIONRETVAL) && (ret == FTW_SKIP_SUBTREE || ret == FTW_SKIP_SIBLINGS))
	ret = 0;
    }

  sv_e = errno;
  if (ctx.objs)
    free_objs (ctx.objs);
  free (ctx.buf);
  errno =  (sv_e);

  return ret;
}

int
FUNC_FTW (const char *path, int (*fcb) (const char *, const STRUCT_STAT *, int), int descriptors);
int
FUNC_FTW (const char *path, int (*fcb) (const char *, const STRUCT_STAT *, int), int descriptors)
{
  return do_it (path, 0, fcb, descriptors, 0);
}

int
FUNC_NFTW (const char *path, int (*fcb) (const char *, const STRUCT_STAT *, int , struct FTW *), int descriptors, int flags);
int
FUNC_NFTW (const char *path, int (*fcb) (const char *, const STRUCT_STAT *, int , struct FTW *), int descriptors, int flags)
{
  return do_it (path, 1, fcb, descriptors, flags);
}
