// 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* new) {
    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* new, int flag) {
    return check2fds(fd1, fd2, ENOSYS);
}

__EXPORT
int symlinkat(const char* existing, int fd, const char* new) {
    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);
}
