/*
 * Copyright 2017, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */

#include <autoconf.h>
#include <sel4muslcsys/gen_config.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <sel4/sel4.h>

#include <sys/resource.h>
#include <sys/mman.h>
#include <sys/uio.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <bits/syscall.h>

#include <sel4utils/util.h>

#include <muslcsys/io.h>
#include "arch_stdio.h"

#define FD_TABLE_SIZE(x) (sizeof(muslcsys_fd_t) * (x))
/* this implementation does not allow users to close STDOUT or STDERR, so they can't be freed */
#define FREE_FD_TABLE_SIZE(x) (sizeof(int) * ((x) - FIRST_USER_FD))

static void *cpio_archive_symbol;
static unsigned long cpio_archive_len;
static muslcsys_cpio_get_file_fn_t cpio_get_file_impl;

/* We need to wrap this in the config to prevent linker errors */
#ifdef CONFIG_LIB_SEL4_MUSLC_SYS_CPIO_FS
extern char _cpio_archive[];
#endif

/* file table, indexed by file descriptor */
static muslcsys_fd_t *fd_table = NULL;
/* stack of free file descriptors */
static int *free_fd_table = NULL;
/* head of the stack */
static int free_fd_table_index;
/* total number of fds */
static int num_fds = 256;

void add_free_fd(int fd)
{
    get_fd_struct(fd)->filetype = FILE_TYPE_FREE;
    free_fd_table_index++;
    assert(free_fd_table_index < num_fds);
    free_fd_table[free_fd_table_index] = fd;
}

int get_free_fd(void)
{
    if (free_fd_table_index == -1) {
        return -EMFILE;
    }

    free_fd_table_index--;
    return free_fd_table[free_fd_table_index + 1];
}

int valid_fd(int fd)
{
    return fd < num_fds && fd >= FIRST_USER_FD;
}

static int allocate_file_table(void)
{
    fd_table = malloc(FD_TABLE_SIZE(num_fds));
    if (fd_table == NULL) {
        return -ENOMEM;
    }

    free_fd_table = malloc(FREE_FD_TABLE_SIZE(num_fds));
    if (free_fd_table == NULL) {
        free(fd_table);
        return -ENOMEM;
    }

    free_fd_table_index = -1;

    /* populate free list */
    for (int i = FIRST_USER_FD; i < num_fds; i++) {
        add_free_fd(i);
    }

    return 0;
}

int grow_fds(int how_much)
{
    int new_num_fds = num_fds + how_much;

    /* Ensure file table exists */
    if (fd_table == NULL) {
        if (allocate_file_table() == -ENOMEM) {
            return -ENOMEM;
        }
    }

    /* allocate new arrays */
    muslcsys_fd_t *new_fd_table = malloc(FD_TABLE_SIZE(new_num_fds));
    if (!new_fd_table) {
        LOG_ERROR("Failed to allocate new_vfds\n");
        return -ENOMEM;
    }

    int *new_free_fd_table = malloc(FREE_FD_TABLE_SIZE(new_num_fds));
    if (!new_free_fd_table) {
        free(new_fd_table);
        ZF_LOGE("Failed to allocate free fd table\n");
        return -ENOMEM;
    }

    /* copy old contents */
    memcpy(new_free_fd_table, free_fd_table, FREE_FD_TABLE_SIZE(num_fds));
    memcpy(new_fd_table, fd_table, FD_TABLE_SIZE(num_fds));

    /* free old tables */
    free(fd_table);
    free(free_fd_table);

    /* update global pointers */
    fd_table = new_fd_table;
    free_fd_table = new_free_fd_table;

    /* Update the size */
    num_fds = new_num_fds;

    /* add all of the new available fds to the free list */
    for (int i = num_fds; i < new_num_fds; i++) {
        add_free_fd(i);
    }
    return 0;
}

int allocate_fd()
{
    if (fd_table == NULL) {
        if (allocate_file_table() == -ENOMEM) {
            return -ENOMEM;
        }
    }

    return get_free_fd();
}

muslcsys_fd_t *get_fd_struct(int fd)
{
    assert(fd < num_fds && fd >= FIRST_USER_FD);
    return &fd_table[fd - FIRST_USER_FD];
}

static size_t sys_platform_write(void *data, size_t count)
{
    char *realdata = data;
    return __arch_write(realdata, count);
}

static long sys_open_impl(const char *pathname, int flags, mode_t mode)
{
    /* mask out flags we can support */
    flags &= ~O_LARGEFILE;
    /* only support reading in basic modes */
    if (flags != O_RDONLY) {
        ZF_LOGE("Open only supports O_RDONLY, not 0x%x on %s\n", flags, pathname);
        assert(flags == O_RDONLY);
        return -EINVAL;
    }
    /* as we do not support create, ignore the mode */
    long unsigned int size;
    char *file = NULL;
    if (cpio_get_file_impl && cpio_archive_symbol) {
        file = cpio_get_file_impl(cpio_archive_symbol, cpio_archive_len, pathname, &size);
        if (!file && strncmp(pathname, "./", 2) == 0) {
            file = cpio_get_file_impl(cpio_archive_symbol, cpio_archive_len, pathname + 2, &size);
        }
    }
    if (!file) {
        ZF_LOGE("Failed to open file %s\n", pathname);
        return -ENOENT;
    }
    int fd = allocate_fd();
    if (fd == -EMFILE) {
        ZF_LOGE("Out of fds!\n");
        return -EMFILE;
    }

    muslcsys_fd_t *fds = get_fd_struct(fd);
    fds->filetype = FILE_TYPE_CPIO;
    fds->data = malloc(sizeof(cpio_file_data_t));
    if (!fds->data) {
        ZF_LOGE("Malloc failed\n");
        add_free_fd(fd);
        return -ENOMEM;
    }
    cpio_file_data_t *fd_data = (cpio_file_data_t *)fds->data;
    fd_data->start = file;
    fd_data->size = size;
    fd_data->current = 0;
    return fd;
}

long sys_open(va_list ap)
{
    const char *pathname = va_arg(ap, const char *);
    int flags = va_arg(ap, int);
    mode_t mode = va_arg(ap, mode_t);

    return sys_open_impl(pathname, flags, mode);
}

long sys_openat(va_list ap)
{
    int dirfd = va_arg(ap, int);
    const char *pathname = va_arg(ap, const char *);
    int flags = va_arg(ap, int);
    mode_t mode = va_arg(ap, mode_t);

    if (dirfd != AT_FDCWD) {
        ZF_LOGE("Openat only supports relative path to the current working directory\n");
        return -EINVAL;
    }

    return sys_open_impl(pathname, flags, mode);
}

long sys_close(va_list ap)
{
    int fd = va_arg(ap, int);
    if (fd < FIRST_USER_FD) {
        assert(!"not implemented");
        return -EBADF;
    }

    if (!valid_fd(fd)) {
        return -EBADF;
    }

    muslcsys_fd_t *fds = get_fd_struct(fd);

    if (fds->filetype == FILE_TYPE_CPIO) {
        free(fds->data);
    } else {
        assert(!"not implemented");
    }
    add_free_fd(fd);
    return 0;
}


static write_buf_fn stdio_write = sys_platform_write;

write_buf_fn sel4muslcsys_register_stdio_write_fn(write_buf_fn write_fn)
{
    write_buf_fn old = stdio_write;
    stdio_write = write_fn;
    return old;
}


/* Writev syscall implementation for muslc. Only implemented for stdin and stdout. */
long sys_writev(va_list ap)
{
    int fildes = va_arg(ap, int);
    struct iovec *iov = va_arg(ap, struct iovec *);
    int iovcnt = va_arg(ap, int);

    long long sum = 0;
    ssize_t ret = 0;

    /* The iovcnt argument is valid if greater than 0 and less than or equal to IOV_MAX. */
    if (iovcnt <= 0 || iovcnt > IOV_MAX) {
        return -EINVAL;
    }

    /* The sum of iov_len is valid if less than or equal to SSIZE_MAX i.e. cannot overflow
       a ssize_t. */
    for (int i = 0; i < iovcnt; i++) {
        sum += (long long)iov[i].iov_len;
        if (sum > SSIZE_MAX) {
            return -EINVAL;
        }
    }

    /* If all the iov_len members in the array are 0, return 0. */
    if (!sum) {
        return 0;
    }

    /* Write the buffer to console if the fd is for stdout or stderr. */
    if (fildes == STDOUT_FILENO || fildes == STDERR_FILENO) {
        if (stdio_write == NULL) {
            ZF_LOGD("No standard out function registered");
        }
        for (int i = 0; i < iovcnt; i++) {
            if (stdio_write == NULL) {
                ret += iov[i].iov_len;
            } else {
                ret += stdio_write(iov[i].iov_base, iov[i].iov_len);
            }
        }
    } else {
        assert(!"Not implemented");
        return -EBADF;
    }

    return ret;
}

long sys_write(va_list ap)
{

    int fd = va_arg(ap, int);
    void *buf = va_arg(ap, void *);
    size_t count = va_arg(ap, size_t);
    /* construct an iovec and call writev */
    struct iovec iov = {.iov_base = buf, .iov_len = count };
    return writev(fd, &iov, 1);
}

long sys_readv(va_list ap)
{
    int fd = va_arg(ap, int);
    struct iovec *iov = va_arg(ap, struct iovec *);
    int iovcnt = va_arg(ap, int);
    int i;
    long read;
    if (fd < FIRST_USER_FD) {
        assert(!"not implemented");
        return -EBADF;
    }

    if (!valid_fd(fd)) {
        return -EBADF;
    }

    /* files can only be opened for reading so no need to check any permissions.
     * just get straight into it
     */
    muslcsys_fd_t *muslc_fd = get_fd_struct(fd);
    if (muslc_fd->filetype != FILE_TYPE_CPIO) {
        assert(!"not implemented");
        return -EINVAL;
    }
    cpio_file_data_t *cpio_fd = muslc_fd->data;
    read = 0;
    for (i = 0; i < iovcnt && cpio_fd->current < cpio_fd->size; i++) {
        long max = cpio_fd->size - cpio_fd->current;
        long len = max < iov[i].iov_len ? max : iov[i].iov_len;
        memcpy(iov[i].iov_base, cpio_fd->start + cpio_fd->current, len);
        cpio_fd->current += len;
        read += len;
    }
    return read;
}

long sys_read(va_list ap)
{
    int fd = va_arg(ap, int);
    void *buf = va_arg(ap, void *);
    size_t count = va_arg(ap, size_t);
    /* construct an iovec and call readv */
    struct iovec iov = {.iov_base = buf, .iov_len = count };
    return readv(fd, &iov, 1);
}

long sys_ioctl(va_list ap)
{
    int fd = va_arg(ap, int);
    int request = va_arg(ap, int);
    (void)request;
    /* muslc does some ioctls to stdout, so just allow these to silently
       go through */
    if (fd == STDOUT_FILENO) {
        return 0;
    }
    assert(!"not implemented");
    return 0;
}

long sys_prlimit64(va_list ap)
{
    pid_t pid = va_arg(ap, pid_t);
    int resource = va_arg(ap, int);
    const struct rlimit *new_limit = va_arg(ap, const struct rlimit *);
    struct rlimit *old_limit = va_arg(ap, struct rlimit *);
    int result = 0;

    /* we have no concept of pids, so ignore this for now */
    (void) pid;

    if (resource == RLIMIT_NOFILE) {
        if (old_limit) {
            old_limit->rlim_cur = num_fds;
            /* pick some arbitrarily big number for max. In practice we are only constrained
             * by how large an array we can malloc */
            old_limit->rlim_max = 65536;
        }

        if (new_limit) {
            if (new_limit->rlim_cur < num_fds) {
                printf("Trying to reduce open file limit. Operation not supported, ignoring\n");
            } else {
                result = grow_fds(new_limit->rlim_cur - num_fds);
            }
        }
    } else {
        assert(!"not implemented");
    }

    return result;
}

static int safe_addition(int a, int b)
{
    return !(a >= 0 && b > INT_MAX - a) &&
           !(a < 0 && b < INT_MAX - a);
}

long sys_lseek(va_list ap)
{
    int fd = va_arg(ap, int);
    off_t offset = va_arg(ap, off_t);
    int whence = va_arg(ap, int);

    if (!valid_fd(fd)) {
        return -EBADF;
    }

    muslcsys_fd_t *muslc_fd = get_fd_struct(fd);
    if (muslc_fd == NULL) {
        return -EBADF;
    }

    if (muslc_fd->filetype != FILE_TYPE_CPIO) {
        assert(!"Not implemented\n");
        return -EBADF;
    }

    /* if its a valid fd it must be a cpio file, we
     * don't support anything else */
    cpio_file_data_t *cpio_fd = muslc_fd->data;

    int new_offset = 0;
    switch (whence) {
    case SEEK_SET:
        new_offset = offset;
        break;
    case SEEK_CUR:
        if (!safe_addition(cpio_fd->current, offset)) {
            return -EOVERFLOW;
        }
        new_offset = cpio_fd->current + offset;
        break;
    case SEEK_END:
        if (offset > 0) {
            /* can't seek beyond the end of the cpio file */
            return -EINVAL;
        }
        new_offset = cpio_fd->size + offset;
        break;
    default:
        return -EINVAL;
    }

    if (new_offset < 0) {
        return -EINVAL;
        /* can't seek past the end of the cpio file */
    } else if (new_offset > cpio_fd->size) {
        return -EINVAL;
    }

    cpio_fd->current = new_offset;

    return new_offset;
}

long syscall(long n, ...);

long sys__llseek(va_list ap)
{
    int fd = va_arg(ap, int);
    uint32_t offset_high = va_arg(ap, uint32_t);
    uint32_t offset_low = va_arg(ap, uint32_t);
    off_t *result = va_arg(ap, off_t *);
    int whence = va_arg(ap, int);
    /* need to directly call syscall to prevent circular call to this function. the llseek function
     * is used when off_t is a 64bit type (see the lseek definition in muslc), Underneath the
     * hood all syscall arguments get cast to a 32bit long before the actual syscall function
     * gets called. This makes calling the old lseek syscall awkward as it will attempt to pull
     * a 64bit off_t off its syscall args, but we had all our arguments forced down to 32bits
     * before they got passed over. Therefore we can actually just pass the high and low
     * and everything will work. Assumptions on endianess */
    long ret = syscall(SYS_lseek, fd, (uint32_t)offset_low, (uint32_t)offset_high, whence);
    if (ret == -1) {
        /* propogate error up. see __syscall_ret to understand */
        return -errno;
    }
    if (result) {
        *result = (off_t)ret;
    }
    return 0;
}

long sys_access(va_list ap)
{
    const char *pathname = va_arg(ap, const char *);
    int mode = va_arg(ap, int);
    /* just try and open. currently we only support reading with the CPIO file system */
    if (mode == F_OK || mode == R_OK) {
        int fd = open(pathname, O_RDONLY, 0);
        if (fd < 0) {
            return -EACCES;
        }
        close(fd);
        return 0;
    }
    ZF_LOGE("Must pass F_OK or R_OK to %s\n", __FUNCTION__);
    return -EACCES;
}

void muslcsys_install_cpio_interface(void *cpio_symbol, unsigned long cpio_len,
                                     muslcsys_cpio_get_file_fn_t fn)
{
    cpio_archive_symbol = cpio_symbol;
    cpio_archive_len = cpio_len;
    cpio_get_file_impl = fn;
}
