// Copyright 2017 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 <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <zircon/process.h>
#include <zircon/processargs.h>
#include <fbl/ref_ptr.h>

#include "blobstore-private.h"
#include <fs/vfs.h>

#ifdef __Fuchsia__
#include <async/loop.h>
#include <fs/async-dispatcher.h>
#endif

namespace {

#ifdef __Fuchsia__

int do_blobstore_mount(int fd, int argc, char** argv) {
    fbl::RefPtr<blobstore::VnodeBlob> vn;
    if (blobstore::blobstore_mount(&vn, fd) < 0) {
        return -1;
    }
    zx_handle_t h = zx_get_startup_handle(PA_HND(PA_USER0, 0));
    if (h == ZX_HANDLE_INVALID) {
        FS_TRACE_ERROR("blobstore: Could not access startup handle to mount point\n");
        return h;
    }

    async::Loop loop;
    fs::AsyncDispatcher dispatcher(loop.async());
    fs::Vfs vfs(&dispatcher);
    zx_status_t status;
    if ((status = vfs.ServeDirectory(fbl::move(vn), zx::channel(h))) != ZX_OK) {
        return status;
    }
    loop.Run();
    return 0;
}

int do_blobstore_check(int fd, int argc, char** argv) {
    fbl::RefPtr<blobstore::Blobstore> vn;
    if (blobstore::blobstore_create(&vn, fd) < 0) {
        return -1;
    }

    return blobstore::blobstore_check(vn);
}

#else

int do_blobstore_add_blob(int fd, int argc, char** argv) {
    if (argc < 1) {
        fprintf(stderr, "Adding a blob requires an additional file argument\n");
        return -1;
    }

    int data_fd = open(argv[0], O_RDONLY, 0644);
    if (data_fd < 0) {
        fprintf(stderr, "error: cannot open '%s'\n", argv[0]);
        return -1;
    }

    // TODO(smklein): Implement
    fprintf(stderr, "Unimplemented: Adding blob %s\n", argv[0]);
    close(data_fd);
    return -1;
}

#endif

int do_blobstore_mkfs(int fd, int argc, char** argv) {
    uint64_t block_count;
    if (blobstore::blobstore_get_blockcount(fd, &block_count)) {
        fprintf(stderr, "blobstore: cannot find end of underlying device\n");
        return -1;
    }
    return blobstore::blobstore_mkfs(fd, block_count);
}

struct {
    const char* name;
    int (*func)(int fd, int argc, char** argv);
    const char* help;
} CMDS[] = {
    {"create", do_blobstore_mkfs, "initialize filesystem"},
    {"mkfs", do_blobstore_mkfs, "initialize filesystem"},
#ifdef __Fuchsia__
    {"mount", do_blobstore_mount, "mount filesystem"},
    {"check", do_blobstore_check, "check filesystem integrity"},
    {"fsck", do_blobstore_check, "check filesystem integrity"},
#else
    {"add", do_blobstore_add_blob, "add a blob to a blobstore image"},
#endif
};

int usage() {
    fprintf(stderr,
#ifdef __Fuchsia__
            "usage: blobstore <command> [ <arg>* ]\n"
            "\n"
            "On Fuchsia, blobstore takes the block device argument by handle.\n"
            "This can make 'blobstore' commands hard to invoke from command line.\n"
            "Try using the [mkfs,fsck,mount,umount] commands instead\n"
#else
            "usage: blobstore <file-or-device>[@<size>] <command> [ <arg>* ]\n"
#endif
            "\n");
    for (unsigned n = 0; n < (sizeof(CMDS) / sizeof(CMDS[0])); n++) {
        fprintf(stderr, "%9s %-10s %s\n", n ? "" : "commands:",
                CMDS[n].name, CMDS[n].help);
    }
    fprintf(stderr, "\n");
    return -1;
}

} // namespace

int main(int argc, char** argv) {
    int fd;
#ifdef __Fuchsia__
    if (argc < 2) {
        return usage();
    }
    char* cmd = argv[1];
    // Block device passed by handle
    fd = FS_FD_BLOCKDEVICE;
    argv += 2;
    argc -= 2;
#else
    if (argc < 3) {
        return usage();
    }
    char* device = argv[1];
    char* cmd = argv[2];

    char* sizestr = nullptr;
    if ((sizestr = strchr(device, '@')) != nullptr) {
        // Create a file with an explicitly requested size
        *sizestr++ = 0;
        char* end;
        size_t size = strtoull(sizestr, &end, 10);
        if (end == sizestr) {
            fprintf(stderr, "blobstore: bad size: %s\n", sizestr);
            return usage();
        }
        switch (end[0]) {
        case 'M':
        case 'm':
            size *= (1024 * 1024);
            end++;
            break;
        case 'G':
        case 'g':
            size *= (1024 * 1024 * 1024);
            end++;
            break;
        }
        if (end[0]) {
            fprintf(stderr, "blobstore: bad size: %s\n", sizestr);
            return usage();
        }

        if ((fd = open(device, O_RDWR | O_CREAT, 0644)) < 0) {
            fprintf(stderr, "error: cannot open '%s'\n", device);
            return -1;
        } else if (ftruncate(fd, size)) {
            fprintf(stderr, "error: cannot truncate device '%s'\n", device);
            return -1;
        }
    } else if ((fd = open(device, O_RDWR, 0644)) < 0) {
        // Open a file without an explicit size
        fprintf(stderr, "error: cannot open '%s'\n", device);
        return -1;
    }
    argv += 3;
    argc -= 3;
#endif
    for (unsigned i = 0; i < sizeof(CMDS) / sizeof(CMDS[0]); i++) {
        if (!strcmp(cmd, CMDS[i].name)) {
            return CMDS[i].func(fd, argc, argv);
        }
    }
    close(fd);
    return usage();
}
