// 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 <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 <fbl/limits.h>
#include <fbl/ref_ptr.h>
#include <fdio/vfs.h>
#include <fs/vfs.h>
#include <zircon/assert.h>

#include <minfs/host.h>
#include <minfs/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;
    fs::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;
    case ZX_ERR_FILE_BIG:
        return EFBIG;
    case ZX_ERR_NO_SPACE:
        return ENOSPC;
    default:
        return EIO;
    }
}

#define FAIL(err)              \
    do {                       \
        errno = (err);         \
        return errno ? -1 : 0; \
    } while (0)
#define STATUS(status) \
    FAIL(status_to_errno(status))

fbl::RefPtr<fs::Vnode> fake_root = nullptr;
fs::Vfs fake_vfs;

int emu_mkfs(const char* path) {
    fbl::unique_fd fd(open(path, O_RDWR));
    if (!fd) {
        fprintf(stderr, "error: could not open path %s\n", path);
        return -1;
    }

    struct stat s;
    if (fstat(fd.get(), &s) < 0) {
        fprintf(stderr, "error: minfs could not find end of file/device\n");
        return -1;
    }

    off_t size = s.st_size / minfs::kMinfsBlockSize;

    fbl::unique_ptr<minfs::Bcache> bc;
    if (minfs::Bcache::Create(&bc, fbl::move(fd), (uint32_t) size) < 0) {
        fprintf(stderr, "error: cannot create block cache\n");
        return -1;
    }

    return minfs_mkfs(fbl::move(bc));
}

int emu_mount(const char* path) {
    fbl::unique_fd fd(open(path, O_RDWR));
    if (!fd) {
        fprintf(stderr, "error: could not open path %s\n", path);
        return -1;
    }

    struct stat s;
    if (fstat(fd.get(), &s) < 0) {
        fprintf(stderr, "error: minfs could not find end of file/device\n");
        return 0;
    }

    off_t size = s.st_size / minfs::kMinfsBlockSize;

    fbl::unique_ptr<minfs::Bcache> bc;
    if (minfs::Bcache::Create(&bc, fbl::move(fd), (uint32_t) size) < 0) {
        fprintf(stderr, "error: cannot create block cache\n");
        return -1;
    }

    fbl::RefPtr<minfs::VnodeMinfs> vn;
    if (minfs_mount(&vn, fbl::move(bc)) < 0) {
        return -1;
    }
    fake_root = vn;
    return 0;
}

int emu_open(const char* path, int flags, mode_t mode) {
    //TODO: fdtab lock
    ZX_DEBUG_ASSERT_MSG(!host_path(path), "'emu_' functions can only operate on target paths");
    int fd;
    if (flags & O_APPEND) {
        errno = ENOTSUP;
        return -1;
    }
    for (fd = 0; fd < MAXFD; fd++) {
        if (fdtab[fd].vn == nullptr) {
            fbl::RefPtr<fs::Vnode> vn_fs;
            fbl::StringPiece str(path + PREFIX_SIZE);
            zx_status_t status = fake_vfs.Open(fake_root, &vn_fs, str, &str, 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_get(fd);
    if (f == nullptr) {
        return -1;
    }
    f->vn->Close();
    memset(f, 0, sizeof(file_t));
    return 0;
}

ssize_t emu_write(int fd, const void* buf, size_t count) {
    file_t* f = file_get(fd);
    if (f == nullptr) {
        return -1;
    }
    size_t actual;
    zx_status_t status = f->vn->Write(buf, count, f->off, &actual);
    if (status == ZX_OK) {
        f->off += actual;
        ZX_DEBUG_ASSERT(actual <= fbl::numeric_limits<ssize_t>::max());
        return static_cast<ssize_t>(actual);
    }

    ZX_DEBUG_ASSERT(status < 0);
    STATUS(status);
}

ssize_t emu_pwrite(int fd, const void* buf, size_t count, off_t off) {
    file_t* f = file_get(fd);
    if (f == nullptr) {
        return -1;
    }
    size_t actual;
    zx_status_t status = f->vn->Write(buf, count, off, &actual);
    if (status == ZX_OK) {
        ZX_DEBUG_ASSERT(actual <= fbl::numeric_limits<ssize_t>::max());
        return static_cast<ssize_t>(actual);
    }

    ZX_DEBUG_ASSERT(status < 0);
    STATUS(status);
}

ssize_t emu_read(int fd, void* buf, size_t count) {
    file_t* f = file_get(fd);
    if (f == nullptr) {
        return -1;
    }
    size_t actual;
    zx_status_t status = f->vn->Read(buf, count, f->off, &actual);
    if (status == ZX_OK) {
        f->off += actual;
        ZX_DEBUG_ASSERT(actual <= fbl::numeric_limits<ssize_t>::max());
        return static_cast<ssize_t>(actual);
    }
    ZX_DEBUG_ASSERT(status < 0);
    STATUS(status);
}

ssize_t emu_pread(int fd, void* buf, size_t count, off_t off) {
    file_t* f = file_get(fd);
    if (f == nullptr) {
        return -1;
    }
    size_t actual;
    zx_status_t status = f->vn->Read(buf, count, off, &actual);
    if (status == ZX_OK) {
        ZX_DEBUG_ASSERT(actual <= fbl::numeric_limits<ssize_t>::max());
        return static_cast<ssize_t>(actual);
    }
    ZX_DEBUG_ASSERT(status < 0);
    STATUS(status);
}

int emu_ftruncate(int fd, off_t len) {
    file_t* f = file_get(fd);
    if (f == nullptr) {
        return -1;
    }
    int r = f->vn->Truncate(len);
    return r < 0 ? -1 : r;
}

off_t emu_lseek(int fd, off_t offset, int whence) {
    file_t* f = file_get(fd);
    if (f == nullptr) {
        return -1;
    }

    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_get(fd);
    if (f == nullptr) {
        return -1;
    }
    STATUS(do_stat(f->vn, s));
}

int emu_stat(const char* fn, struct stat* s) {
    ZX_DEBUG_ASSERT_MSG(!host_path(fn), "'emu_' functions can only operate on target paths");
    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, fbl::StringPiece(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;
    fs::vdircookie_t cookie;
    uint8_t* ptr;
    uint8_t data[DIR_BUFSIZE];
    size_t size;
    struct dirent de;
} MINDIR;

int emu_mkdir(const char* path, mode_t mode) {
    ZX_DEBUG_ASSERT_MSG(!host_path(path), "'emu_' functions can only operate on target paths");
    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;
    }
}

DIR* emu_opendir(const char* name) {
    ZX_DEBUG_ASSERT_MSG(!host_path(name), "'emu_' functions can only operate on target paths");
    fbl::RefPtr<fs::Vnode> vn;
    fbl::StringPiece path(name + PREFIX_SIZE);
    zx_status_t status = fake_vfs.Open(fake_root, &vn, path, &path, 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);
                ent->d_type = vde->type;
                dir->ptr += vde->size;
                dir->size -= vde->size;
                return ent;
            }
            dir->size = 0;
        }
        size_t actual;
        zx_status_t status = dir->vn->Readdir(&dir->cookie, &dir->data, DIR_BUFSIZE, &actual);
        if (status != ZX_OK || actual == 0) {
            break;
        }
        dir->ptr = dir->data;
        dir->size = actual;
    }
    return nullptr;
}

void emu_rewinddir(DIR* dirp) {
    MINDIR* dir = (MINDIR*)dirp;
    dir->size = 0;
    dir->ptr = NULL;
    dir->cookie.n = 0;
}

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;
}
