/*
 * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/uio.h>
#include <utils/util.h>
#include <muslcsys/vsyscall.h>
#include "fsclient.h"

static void *ext_buf;
static int (*ext_open)(const char *name, int flags);
static ssize_t (*ext_read)(int fd, size_t size);
static int64_t (*ext_seek)(int fd, int64_t offset, int whence);
static int (*ext_close)(int fd);

static long fileserver_open(va_list ap)
{
    const char *pathname = va_arg(ap, const char *);
    int flags = va_arg(ap, int);
    return ext_open(pathname, flags);
}

static long fileserver_openat(va_list ap)
{
    int dirfd = va_arg(ap, int);
    const char *pathname = va_arg(ap, const char *);
    int flags = va_arg(ap, int);

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

static long fileserver_close(va_list ap)
{
    int fd = va_arg(ap, int);
    return ext_close(fd);
}

static long fileserver_read(va_list ap)
{
    int fd = va_arg(ap, int);
    void *buf = va_arg(ap, void *);
    size_t count = va_arg(ap, size_t);
    ssize_t total = 0;
    size_t remain = count;
    while (total < count) {
        ssize_t result = ext_read(fd, remain);
        if (result <= 0) {
            return total;
        }
        memcpy(buf + total, ext_buf, result);
        total += result;
        remain -= result;
    }
    return total;
}

static long fileserver_readv(va_list ap)
{
    int fd = va_arg(ap, int);
    struct iovec *iov = va_arg(ap, struct iovec *);
    int iovcnt = va_arg(ap, int);
    ssize_t total = 0;
    int i;
    for (i = 0; i < iovcnt; i++) {
        long iov_offset = 0;
        while (iov_offset < iov[i].iov_len) {
            long read = ext_read(fd, iov[i].iov_len - iov_offset);
            if (read <= 0) {
                return total;
            }
            memcpy(iov[i].iov_base + iov_offset, ext_buf, read);
            iov_offset += read;
            total += read;
        }
    }
    return total;
}

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

    return ext_seek(fd, offset, whence);
}

static long fileserver_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);

    *result = ext_seek(fd, (((uint64_t)offset_high) << 32) | offset_low, whence);
    return 0;
}

void install_fileserver(file_server_interface_t fs_interface)
{
    ext_buf = fs_interface.ext_buf;
    ext_open = fs_interface.ext_open;
    ext_read = fs_interface.ext_read;
    ext_seek = fs_interface.ext_seek;
    ext_close = fs_interface.ext_close;
#ifdef __NR_open
    muslcsys_install_syscall(__NR_open, fileserver_open);
#endif
#ifdef __NR_openat
    muslcsys_install_syscall(__NR_openat, fileserver_openat);
#endif
    muslcsys_install_syscall(__NR_close, fileserver_close);
    muslcsys_install_syscall(__NR_read, fileserver_read);
    muslcsys_install_syscall(__NR_readv, fileserver_readv);
    muslcsys_install_syscall(__NR_lseek, fileserver_lseek);
#ifdef __NR__llseek
    muslcsys_install_syscall(__NR__llseek, fileserver_llseek);
#endif
}
