// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <dirent.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <unistd.h>

#include <errno.h>
#include <sys/stat.h>

#include "unistd.h"

// checkfile, checkfileat, and checkfd let us error out if the object
// doesn't exist, which allows the stubs to be a little more 'real'
static int seterr(int err) {
    if (err) {
        errno = err;
        return -1;
    }
    return 0;
}

static int checkfile(const char* path, int err) {
    struct stat s;
    if (stat(path, &s)) {
        return -1;
    }
    return seterr(err);
}

static int checkfileat(int fd, const char* path, int flags, int err) {
    struct stat s;
    if (fstatat(fd, path, &s, flags)) {
        return -1;
    }
    return seterr(err);
}

static int checkfd(int fd, int err) {
    fdio_t* io;
    if ((io = fd_to_io(fd)) == NULL) {
        errno = EBADF;
        return -1;
    }
    fdio_release(io);
    return seterr(err);
}

static int check2fds(int fd1, int fd2, int err) {
    fdio_t* io;
    if ((io = fd_to_io(fd1)) == NULL) {
        errno = EBADF;
        return -1;
    }
    fdio_release(io);
    if ((io = fd_to_io(fd2)) == NULL) {
        errno = EBADF;
        return -1;
    }
    fdio_release(io);
    return seterr(err);
}

static int checkfilefd(const char* path, int fd, int err) {
    struct stat s;
    if (stat(path, &s)) {
        return -1;
    }
    fdio_t* io;
    if ((io = fd_to_io(fd)) == NULL) {
        errno = EBADF;
        return -1;
    }
    fdio_release(io);
    return seterr(err);
}

static int checksocket(int fd, int sock_err, int err) {
    fdio_t* io = fd_to_io(fd);
    if (io == NULL) {
        errno = EBADF;
        return -1;
    }
    int32_t is_socket = *fdio_get_ioflag(io) & IOFLAG_SOCKET;
    fdio_release(io);
    if (!is_socket) {
        errno = sock_err;
        return -1;
    }
    return seterr(err);
}

static int checkdir(DIR* dir, int err) {
    if (dirfd(dir) < 0) {
        errno = EBADF;
        return -1;
    }
    return seterr(err);
}

// not supported by any filesystems yet
__EXPORT
int symlink(const char* existing, const char* newpath) {
    errno = ENOSYS;
    return -1;
}
__EXPORT
ssize_t readlink(const char* __restrict path, char* __restrict buf, size_t bufsize) {
    // EINVAL = not symlink
    return checkfile(path, EINVAL);
}

// creating things we don't have plumbing for yet
__EXPORT
int mkfifo(const char *path, mode_t mode) {
    errno = ENOSYS;
    return -1;
}
__EXPORT
int mknod(const char* path, mode_t mode, dev_t dev) {
    errno = ENOSYS;
    return -1;
}

// no permissions support yet
__EXPORT
int chown(const char *path, uid_t owner, gid_t group) {
    return checkfile(path, ENOSYS);
}
__EXPORT
int fchown(int fd, uid_t owner, gid_t group) {
    return checkfd(fd, ENOSYS);
}
__EXPORT
int lchown(const char *path, uid_t owner, gid_t group) {
    return checkfile(path, ENOSYS);
}

// no permissions support, but treat rwx bits as don't care rather than error
__EXPORT
int chmod(const char *path, mode_t mode) {
    return checkfile(path, (mode & (~0777)) ? ENOSYS : 0);
}
__EXPORT
int fchmod(int fd, mode_t mode) {
    return checkfd(fd, (mode & (~0777)) ? ENOSYS : 0);
}
__EXPORT
int fchmodat(int fd, const char* path, mode_t mode, int flags) {
    if (flags & ~AT_SYMLINK_NOFOLLOW) {
        errno = EINVAL;
        return -1;
    }

    return checkfileat(fd, path, flags, (mode & (~0777)) ? ENOSYS : 0);
}

__EXPORT
int access(const char* path, int mode) {
    return checkfile(path, 0);
}

__EXPORT
void sync(void) {
}

// at the moment our unlink works on all fs objects
__EXPORT
int rmdir(const char* path) {
    return unlink(path);
}

// tty stubbing.
__EXPORT
int ttyname_r(int fd, char* name, size_t size) {
    if (!isatty(fd)) {
        return ENOTTY;
    }

    return checkfd(fd, ENOSYS);
}

__EXPORT
int sendmmsg(int fd, struct mmsghdr* msgvec, unsigned int vlen, unsigned int flags) {
    return checksocket(fd, ENOTSOCK, ENOSYS);
}

__EXPORT
int recvmmsg(int fd, struct mmsghdr* msgvec, unsigned int vlen, unsigned int flags, struct timespec* timeout) {
    return checksocket(fd, ENOTSOCK, ENOSYS);
}

__EXPORT
int sockatmark(int fd) {
    // ENOTTY is sic.
    return checksocket(fd, ENOTTY, ENOSYS);
}

__EXPORT
int fchownat(int fd, const char* path, uid_t uid, gid_t gid, int flag) {
    return checkfd(fd, ENOSYS);
}

__EXPORT
int linkat(int fd1, const char* existing, int fd2, const char* newpath, int flag) {
    return check2fds(fd1, fd2, ENOSYS);
}

__EXPORT
int symlinkat(const char* existing, int fd, const char* newpath) {
    return checkfilefd(existing, fd, ENOSYS);
}

__EXPORT
ssize_t readlinkat(int fd, const char* __restrict path, char* __restrict buf, size_t bufsize) {
    return checkfilefd(path, fd, ENOSYS);
}

__EXPORT
void seekdir(DIR* dir, long loc) {
}

__EXPORT
long telldir(DIR* dir) {
    return checkdir(dir, ENOSYS);
}

__EXPORT
int posix_fadvise(int fd, off_t base, off_t len, int advice) {
    return checkfd(fd, ENOSYS);
}

__EXPORT
int posix_fallocate(int fd, off_t base, off_t len) {
    return checkfd(fd, ENOSYS);
}

__EXPORT
int readdir_r(DIR* dir, struct dirent* entry, struct dirent** result) {
    return checkdir(dir, ENOSYS);
}
