#include <bits/getdents.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>

extern "C"
{
    DIR* opendir(const char* path)
    {
        DIR* dp = (DIR*)malloc(sizeof(DIR));
        if (!dp) { return nullptr; }

        int fd = open(path, O_RDONLY | O_DIRECTORY);
        if (fd < 0)
        {
            free(dp);
            return nullptr;
        }

        dp->_fd = fd;

        return dp;
    }

    struct dirent* readdir(DIR* stream)
    {
        // FIXME: Very hackish, right now luna_dirent and dirent have the same layout.
        static luna_dirent ent;

        long rc = syscall(SYS_getdents, stream->_fd, &ent, 1);
        if (rc < 0)
        {
            errno = (int)-rc;
            return nullptr;
        }

        // End-of-file (no more directory entries)
        if (rc < 1) return nullptr;

        return (struct dirent*)&ent;
    }

    int closedir(DIR* stream)
    {
        if (close(stream->_fd) < 0) return -1;

        free(stream);

        return 0;
    }
}