// 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.

// for S_IF*
#define _XOPEN_SOURCE
#include "host.h"

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <fs/vfs.h>

#include <fdio/vfs.h>
#include "minfs.h"
#include "minfs-private.h"

static zx_status_t do_stat(fbl::RefPtr<fs::Vnode> vn, struct stat* s) {
    vnattr_t a;
    zx_status_t status = vn->Getattr(&a);
    if (status == ZX_OK) {
        memset(s, 0, sizeof(struct stat));
        s->st_mode = a.mode;
        s->st_size = a.size;
        s->st_ino = a.inode;
        s->st_ctime = a.create_time;
        s->st_mtime = a.modify_time;
    }
    return status;
}

typedef struct {
    fbl::RefPtr<fs::Vnode> vn;
    uint64_t off;
    vdircookie_t dircookie;
} file_t;

#define MAXFD 64

static file_t fdtab[MAXFD];

#define FD_MAGIC 0x45AB0000

static file_t* file_get(int fd) {
    if (((fd)&0xFFFF0000) != FD_MAGIC) {
        return nullptr;
    }
    fd &= 0x0000FFFF;
    if ((fd < 0) || (fd >= MAXFD)) {
        return nullptr;
    }
    if (fdtab[fd].vn == nullptr) {
        return nullptr;
    }
    return fdtab + fd;
}

int status_to_errno(zx_status_t status) {
    switch (status) {
    case ZX_OK:
        return 0;
    default:
        return EIO;
    }
}

#define FAIL(err)              \
    do {                       \
        errno = (err);         \
        return errno ? -1 : 0; \
    } while (0)
#define STATUS(status) \
    FAIL(status_to_errno(status))
#define FILE_GET(f, fd)                   \
    do {                                  \
        if ((f = file_get(fd)) == nullptr) { \
            FAIL(EBADF);                  \
        }                                 \
    } while (0)
#define FILE_WRAP(f, fd, name, args...) \
    do {                                \
        if ((f = file_get(fd)) == nullptr) \
            return name(args);          \
    } while (0)
#define PATH_WRAP(path, name, args...) \
    do {                               \
        if (check_path(path))          \
            return name(args);         \
    } while (0)

fbl::RefPtr<fs::Vnode> fake_root;

static inline int check_path(const char* path) {
    if (strncmp(path, PATH_PREFIX, PREFIX_SIZE) || (fake_root == nullptr)) {
        return -1;
    }
    return 0;
}

int emu_open(const char* path, int flags, mode_t mode) {
    //TODO: fdtab lock
    PATH_WRAP(path, open, path, flags, mode);
    int fd;
    for (fd = 0; fd < MAXFD; fd++) {
        if (fdtab[fd].vn == nullptr) {
            const char* pathout = nullptr;
            fbl::RefPtr<fs::Vnode> vn_fs;
            zx_status_t status = minfs::vfs.Open(fake_root, &vn_fs, path + PREFIX_SIZE, &pathout, flags, mode);
            if (status < 0) {
                STATUS(status);
            }
            fdtab[fd].vn = fbl::RefPtr<fs::Vnode>::Downcast(vn_fs);
            return fd | FD_MAGIC;
        }
    }
    FAIL(EMFILE);
}

int emu_close(int fd) {
    //TODO: fdtab lock
    file_t* f;
    FILE_WRAP(f, fd, close, fd);
    f->vn->Close();
    memset(f, 0, sizeof(file_t));
    return 0;
}

int emu_mkdir(const char* path, mode_t mode) {
    PATH_WRAP(path, mkdir, path, mode);
    mode = S_IFDIR;
    int fd = emu_open(path, O_CREAT | O_EXCL, S_IFDIR | (mode & 0777));
    if (fd >= 0) {
        emu_close(fd);
        return 0;
    } else {
        return fd;
    }
}

ssize_t emu_read(int fd, void* buf, size_t count) {
    file_t* f;
    FILE_WRAP(f, fd, read, fd, buf, count);
    ssize_t r = f->vn->Read(buf, count, f->off);
    if (r > 0) {
        f->off += r;
    }
    return r;
}

ssize_t emu_write(int fd, const void* buf, size_t count) {
    file_t* f;
    FILE_WRAP(f, fd, write, fd, buf, count);
    ssize_t r = f->vn->Write(buf, count, f->off);
    if (r > 0) {
        f->off += r;
    }
    return r;
}

off_t emu_lseek(int fd, off_t offset, int whence) {
    file_t* f;
    FILE_WRAP(f, fd, lseek, fd, offset, whence);

    uint64_t old = f->off;
    uint64_t n;
    vnattr_t a;

    switch (whence) {
    case SEEK_SET:
        if (offset < 0) {
            FAIL(EINVAL);
        }
        f->off = offset;
        break;
    case SEEK_END:
        if (f->vn->Getattr(&a)) {
            FAIL(EINVAL);
        }
        old = a.size;
    // fall through
    case SEEK_CUR:
        n = old + offset;
        if (offset < 0) {
            if (n >= old) {
                FAIL(EINVAL);
            }
        } else {
            if (n < old) {
                FAIL(EINVAL);
            }
        }
        f->off = n;
        break;
    default:
        FAIL(EINVAL);
    }
    return f->off;
}

int emu_fstat(int fd, struct stat* s) {
    file_t* f;
    FILE_WRAP(f, fd, fstat, fd, s);
    STATUS(do_stat(f->vn, s));
}

int emu_unlink(const char* path) {
    PATH_WRAP(path, unlink, path);
    fbl::RefPtr<fs::Vnode> vn;
    zx_status_t status = minfs::vfs.Walk(fake_root, &vn, path + PREFIX_SIZE, &path);
    if (status == ZX_OK) {
        status = vn->Unlink(path, strlen(path), false);
        vn->Close();
    }
    STATUS(status);
}

int emu_rename(const char* oldpath, const char* newpath) {
    STATUS(ZX_ERR_NOT_SUPPORTED);
}

int emu_stat(const char* fn, struct stat* s) {
    PATH_WRAP(fn, stat, fn, s);
    fbl::RefPtr<fs::Vnode> vn = fake_root;
    fbl::RefPtr<fs::Vnode> cur = fake_root;
    zx_status_t status;
    const char* nextpath = nullptr;
    size_t len;

    fn += PREFIX_SIZE;
    do {
        while (fn[0] == '/') {
            fn++;
        }
        if (fn[0] == 0) {
            fn = ".";
        }
        len = strlen(fn);
        nextpath = strchr(fn, '/');
        if (nextpath != nullptr) {
            len = nextpath - fn;
            nextpath++;
        }
        fbl::RefPtr<fs::Vnode> vn_fs;
        status = cur->Lookup(&vn_fs, fn, len);
        if (status != ZX_OK) {
            return -ENOENT;
        }
        vn = fbl::RefPtr<fs::Vnode>::Downcast(vn_fs);
        if (cur != fake_root) {
            cur->Close();
        }
        cur = vn;
        fn = nextpath;
    } while (nextpath != nullptr);

    status = do_stat(vn, s);
    if (vn != fake_root) {
        vn->Close();
    }
    STATUS(status);
}

#define DIR_BUFSIZE 2048

typedef struct MINDIR {
    uint64_t magic;
    fbl::RefPtr<fs::Vnode> vn;
    vdircookie_t cookie;
    uint8_t* ptr;
    uint8_t data[DIR_BUFSIZE];
    size_t size;
    struct dirent de;
} MINDIR;

DIR* emu_opendir(const char* name) {
    PATH_WRAP(name, opendir, name);
    fbl::RefPtr<fs::Vnode> vn;
    zx_status_t status = minfs::vfs.Open(fake_root, &vn, name + PREFIX_SIZE, &name, O_RDONLY, 0);
    if (status != ZX_OK) {
        return nullptr;
    }
    MINDIR* dir = (MINDIR*)calloc(1, sizeof(MINDIR));
    dir->magic = minfs::kMinfsMagic0;
    dir->vn = fbl::RefPtr<fs::Vnode>::Downcast(vn);
    return (DIR*) dir;
}

struct dirent* emu_readdir(DIR* dirp) {
    MINDIR* dir = (MINDIR*)dirp;
    for (;;) {
        if (dir->size >= sizeof(vdirent_t)) {
            vdirent_t* vde = (vdirent_t*)dir->ptr;
            if (dir->size >= vde->size) {
                struct dirent* ent = &dir->de;
                strcpy(ent->d_name, vde->name);
                dir->ptr += vde->size;
                dir->size -= vde->size;
                return ent;
            }
            dir->size = 0;
        }
        zx_status_t status = dir->vn->Readdir(&dir->cookie, &dir->data, DIR_BUFSIZE);
        if (status <= 0) {
            break;
        }
        dir->ptr = dir->data;
        dir->size = status;
    }
    return nullptr;
}

int emu_closedir(DIR* dirp) {
    if (((uint64_t*)dirp)[0] != minfs::kMinfsMagic0) {
        return closedir(dirp);
    }

    MINDIR* dir = (MINDIR*)dirp;
    dir->vn->Close();
    free(dirp);

    return 0;
}
