/*
 * Copyright (C) 2008 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

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

#include <private/ScopedPthreadMutexLocker.h>

struct DIR {
  int fd_;
  size_t available_bytes_;
  dirent* next_;
  pthread_mutex_t mutex_;
  dirent buff_[15];
};

static DIR* __allocate_DIR(int fd) {
  DIR* d = reinterpret_cast<DIR*>(malloc(sizeof(DIR)));
  if (d == NULL) {
    return NULL;
  }
  d->fd_ = fd;
  d->available_bytes_ = 0;
  d->next_ = NULL;
  pthread_mutex_init(&d->mutex_, NULL);
  return d;
}

int dirfd(DIR* dirp) {
  return dirp->fd_;
}

DIR* fdopendir(int fd) {
  // Is 'fd' actually a directory?
  struct stat sb;
  if (fstat(fd, &sb) == -1) {
    return NULL;
  }
  if (!S_ISDIR(sb.st_mode)) {
    errno = ENOTDIR;
    return NULL;
  }

  return __allocate_DIR(fd);
}

DIR* opendir(const char* path) {
  int fd = open(path, O_RDONLY | O_DIRECTORY);
  return (fd != -1) ? __allocate_DIR(fd) : NULL;
}

static bool __fill_DIR(DIR* d) {
  int rc = TEMP_FAILURE_RETRY(getdents(d->fd_, d->buff_, sizeof(d->buff_)));
  if (rc <= 0) {
    return false;
  }
  d->available_bytes_ = rc;
  d->next_ = d->buff_;
  return true;
}

static dirent* __readdir_locked(DIR* d) {
  if (d->available_bytes_ == 0 && !__fill_DIR(d)) {
    return NULL;
  }

  dirent* entry = d->next_;
  d->next_ = reinterpret_cast<dirent*>(reinterpret_cast<char*>(entry) + entry->d_reclen);
  d->available_bytes_ -= entry->d_reclen;
  return entry;
}

dirent* readdir(DIR* d) {
  ScopedPthreadMutexLocker locker(&d->mutex_);
  return __readdir_locked(d);
}

int readdir_r(DIR* d, dirent* entry, dirent** result) {
  int saved_errno = errno;

  *result = NULL;
  errno = 0;

  ScopedPthreadMutexLocker locker(&d->mutex_);

  dirent* next = __readdir_locked(d);
  if (errno != 0 && next == NULL) {
    return errno;
  }

  if (next != NULL) {
    memcpy(entry, next, next->d_reclen);
    *result = entry;
  }
  errno = saved_errno;
  return 0;
}

int closedir(DIR* d) {
  if (d == NULL) {
    errno = EINVAL;
    return -1;
  }

  int fd = d->fd_;
  pthread_mutex_destroy(&d->mutex_);
  free(d);
  return close(fd);
}

void rewinddir(DIR* d) {
  ScopedPthreadMutexLocker locker(&d->mutex_);
  lseek(d->fd_, 0, SEEK_SET);
  d->available_bytes_ = 0;
}

int scandir(const char* path, dirent*** namelist,
            int(*filter)(const dirent*),
            int(*compar)(const dirent**, const dirent**))
{
  int n_elem = 0;
  dirent* this_de, *de;
  dirent** de_list = NULL;
  int de_list_size = 0;

  DIR* d = opendir(path);
  if (d == NULL) {
    return -1;
  }

  while ((this_de = readdir(d)) != NULL) {
    if (filter != NULL && (*filter)(this_de) == 0) {
      continue;
    }
    if (n_elem == 0) {
      de_list_size = 4;
      de_list = (dirent**) malloc(sizeof(dirent*) * de_list_size);
      if (de_list == NULL) {
        return -1;
      }
    } else if (n_elem == de_list_size) {
      de_list_size += 10;
      dirent** de_list_new = (dirent**) realloc(de_list, sizeof(dirent*) * de_list_size);
      if (de_list_new == NULL) {
        free(de_list);
        return -1;
      }
      de_list = de_list_new;
    }
    de = (dirent*) malloc(sizeof(dirent));
    *de = *this_de;
    de_list[n_elem++] = de;
  }
  closedir(d);
  if (n_elem && compar) {
    qsort(de_list, n_elem, sizeof(dirent*), (int (*)(const void*, const void*)) compar);
  }
  *namelist = de_list;
  return n_elem;
}

int alphasort(const struct dirent** a, const struct dirent** b) {
  return strcoll((*a)->d_name, (*b)->d_name);
}
