#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <luna/dirent.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

extern "C"
{
    DIR* opendir(const char* path)
    {
        int dirfd = open(path, O_RDONLY | O_DIRECTORY);
        if (dirfd < 0) return NULL;
        return fdopendir(dirfd);
    }

    DIR* fdopendir(int fd)
    {
        if (fd < 0) return NULL;
        DIR* result = (DIR*)malloc(sizeof(DIR));
        if (!result) return NULL;
        result->d_dirfd = fd;
        return result;
    }

    int closedir(DIR* stream)
    {
        int status = close(stream->d_dirfd);
        if (status < 0)
        {
            int savederr = errno;
            free(stream);
            errno = savederr; // free might reset errno. We don't want that.
        }
        else { free(stream); }
        return status;
    }

    struct dirent* readdir(DIR* stream)
    {
        static struct dirent result;
        struct luna_dirent ent;
        ssize_t nread = getdents(stream->d_dirfd, &ent, 1); // FIXME: Use a buffer to avoid too many system calls.
        if (nread <= 0) return NULL;                        // Either EOF or error.
        result.d_ino = ent.inode;
        result.d_reclen = sizeof(result);
        result.d_off = ent.offset;
        result.d_type = 0;
        strlcpy(result.d_name, ent.name, NAME_MAX);
        return &result;
    }
}