// Copyright 2018 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 <fcntl.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>

#include <blkctl/blkctl.h>
#include <blkctl/command.h>
#include <fs-management/fvm.h>
#include <fs-management/ramdisk.h>
#include <fvm/fvm.h>
#include <lib/zx/time.h>
#include <zircon/device/block.h>
#include <zircon/device/device.h>
#include <zircon/errors.h>
#include <zircon/status.h>
#include <zircon/types.h>

#include "fvm.h"
#include "generic.h"

namespace blkctl {
namespace fvm {
namespace {

bool SupportsFvmQuery(int fd) {
    if (fd < 0) {
        return false;
    }
    fvm_info_t info;
    memset(&info, 0, sizeof(info));
    return ioctl_block_fvm_query(fd, &info) != ZX_ERR_NOT_SUPPORTED;
}

bool SupportsFvmVSliceQuery(int fd) {
    if (fd < 0) {
        return false;
    }
    query_request_t request;
    query_response_t response;
    memset(&request, 0, sizeof(request));
    memset(&response, 0, sizeof(response));
    return ioctl_block_fvm_vslice_query(fd, &request, &response) != ZX_ERR_NOT_SUPPORTED;
}

zx_status_t CheckFvm(int fd) {
    if (!SupportsFvmQuery(fd) && !SupportsFvmVSliceQuery(fd)) {
        fprintf(stderr, "device does not appear to be an FVM volume or partition\n");
        return ZX_ERR_INVALID_ARGS;
    }
    return ZX_OK;
}

zx_status_t CheckFvmVolume(int fd) {
    if (!SupportsFvmQuery(fd)) {
        fprintf(stderr, "device does not appear to be an FVM volume\n");
        return ZX_ERR_INVALID_ARGS;
    }
    return ZX_OK;
}

zx_status_t CheckFvmPartition(int fd) {
    if (!SupportsFvmVSliceQuery(fd)) {
        fprintf(stderr, "device does not appear to be an FVM partition\n");
        return ZX_ERR_INVALID_ARGS;
    }
    return ZX_OK;
}

} // namespace

zx_status_t Init::Run() {
    zx_status_t rc;
    ssize_t res;
    BlkCtl* cmdline = this->cmdline();

    const char* dev;
    int fd;
    size_t slice_size;
    if ((rc = cmdline->GetStrArg("device", &dev)) != ZX_OK ||
        (rc = cmdline->GetNumArg("slice_size", &slice_size)) != ZX_OK ||
        (rc = cmdline->ArgsDone()) != ZX_OK || (rc = OpenReadable(dev, &fd)) != ZX_OK) {
        return rc;
    }
    char path[PATH_MAX];
    if ((res = ioctl_device_get_topo_path(fd, path, sizeof(path))) < 0) {
        rc = static_cast<zx_status_t>(res);
        fprintf(stderr, "failed to get topological path: %s\n", zx_status_get_string(rc));
        return rc;
    }
    if ((rc = cmdline->Confirm()) != ZX_OK || (rc = ReopenWritable(&fd)) != ZX_OK) {
        return rc;
    }
    if ((rc = fvm_init(fd, slice_size)) != ZX_OK) {
        fprintf(stderr, "fvm_init failed: %s\n", zx_status_get_string(rc));
        return rc;
    }
    if ((res = ioctl_device_bind(fd, kDriver, strlen(kDriver))) < 0) {
        rc = static_cast<zx_status_t>(res);
        fprintf(stderr, "could not bind fvm driver: %s\n", zx_status_get_string(rc));
        return rc;
    }
    char name[PATH_MAX];
    snprintf(name, sizeof(name), "%s/fvm", path);
    if (wait_for_device(name, zx::sec(3).get()) != 0) {
        fprintf(stderr, "timed out waiting for fvm driver to bind\n");
        return ZX_ERR_TIMED_OUT;
    }
    printf("%s created\n", name);
    return ZX_OK;
}

zx_status_t Dump::Run() {
    zx_status_t rc;
    ssize_t res;
    BlkCtl* cmdline = this->cmdline();

    const char* dev;
    int fd;
    fvm_info_t info;
    if ((rc = cmdline->GetStrArg("device", &dev)) != ZX_OK || (rc = cmdline->ArgsDone()) != ZX_OK ||
        (rc = OpenReadable(dev, &fd)) != ZX_OK || (rc = CheckFvm(fd)) != ZX_OK) {
        return rc;
    }
    if ((res = ioctl_block_fvm_query(fd, &info)) < 0) {
        rc = static_cast<zx_status_t>(res);
        fprintf(stderr, "ioctl_block_fvm_query failed: %s\n", zx_status_get_string(rc));
        return rc;
    }
    generic::Dump baseCmd(cmdline);
    if ((rc = cmdline->UngetArgs(1)) != ZX_OK || (rc = baseCmd.Run()) != ZX_OK) {
        return rc;
    }
    printf("%16s: %zu\n", "FVM slice size", info.slice_size);
    printf("%16s: %zu\n", "FVM slice count", info.vslice_count);
    return ZX_OK;
}

zx_status_t Add::Run() {
    zx_status_t rc;
    ssize_t res;
    BlkCtl* cmdline = this->cmdline();

    const char* dev;
    int fd;
    alloc_req_t request;
    memset(&request, 0, sizeof(request));
    const char* name;
    if ((rc = cmdline->GetStrArg("device", &dev)) != ZX_OK ||
        (rc = cmdline->GetStrArg("name", &name)) != ZX_OK ||
        (rc = cmdline->GetNumArg("slices", &request.slice_count)) != ZX_OK) {
        return rc;
    }
    const char* guid;

    rc = cmdline->GetStrArg("guid", &guid, true /* optional */);

    if (rc == ZX_ERR_NOT_FOUND) {
        GenerateGuid(request.type, sizeof(request.type));
    } else if (rc != ZX_OK || (rc = ParseGuid(guid, request.type, sizeof(request.type))) != ZX_OK) {
        return rc;
    }
    if ((rc = cmdline->ArgsDone()) != ZX_OK ||
        (rc = OpenReadable(dev, &fd)) != ZX_OK || (rc = CheckFvmVolume(fd)) != ZX_OK ||
        (rc = cmdline->Confirm()) != ZX_OK || (rc = ReopenWritable(&fd)) != ZX_OK) {
        return rc;
    }
    GenerateGuid(request.guid, sizeof(request.guid));
    if ((res = ioctl_block_fvm_alloc_partition(fd, &request)) < 0) {
        rc = static_cast<zx_status_t>(res);
        fprintf(stderr, "ioctl_block_fvm_alloc_partition failed: %s\n", zx_status_get_string(rc));
        return rc;
    }
    printf("added partition '%s' as ", name);
    PrintGuid(request.guid, sizeof(request.guid));
    printf("\n");
    return ZX_OK;
}

zx_status_t Query::Run() {
    zx_status_t rc;
    ssize_t res;
    BlkCtl* cmdline = this->cmdline();

    const char* dev;
    int fd;
    if ((rc = cmdline->GetStrArg("device", &dev)) != ZX_OK || (rc = cmdline->ArgsDone()) != ZX_OK ||
        (rc = OpenReadable(dev, &fd)) != ZX_OK || (rc = CheckFvmPartition(fd)) != ZX_OK) {
        return rc;
    }
    fvm_info_t info;
    if ((res = ioctl_block_fvm_query(fd, &info)) < 0) {
        rc = static_cast<zx_status_t>(res);
        fprintf(stderr, "ioctl_block_fvm_query failed: %s\n", zx_status_get_string(rc));
        return rc;
    }
    query_request_t request;
    query_response_t response;
    request.count = 1;
    printf("Allocated ranges:\n");
    size_t end = 0;
    for (size_t off = 0; off < info.vslice_count; off = end) {
        request.vslice_start[0] = off;
        if ((res = ioctl_block_fvm_vslice_query(fd, &request, &response)) < 0) {
            rc = static_cast<zx_status_t>(res);
            fprintf(stderr, "ioctl_block_fvm_vslice_query failed: %s\n", zx_status_get_string(rc));
            return rc;
        }
        ZX_DEBUG_ASSERT(response.count == 1);
        ZX_DEBUG_ASSERT(response.vslice_range[0].count != 0);
        end = off + response.vslice_range[0].count;
        if (response.vslice_range[0].allocated) {
            printf("  <0x%016" PRIx64 ", 0x%016" PRIx64 ">:   slices %zu through %zu\n",
                   static_cast<uint64_t>(off * info.slice_size),
                   static_cast<uint64_t>((end * info.slice_size) - 1), off, end);
        }
    }
    return ZX_OK;
}

zx_status_t Extend::Run() {
    zx_status_t rc;
    ssize_t res;
    BlkCtl* cmdline = this->cmdline();

    const char* dev;
    int fd;
    extend_request_t request;
    if ((rc = cmdline->GetStrArg("device", &dev)) != ZX_OK ||
        (rc = cmdline->GetNumArg("start", &request.offset)) != ZX_OK ||
        (rc = cmdline->GetNumArg("length", &request.length)) != ZX_OK ||
        (rc = cmdline->ArgsDone()) != ZX_OK || (rc = OpenReadable(dev, &fd)) != ZX_OK ||
        (rc = CheckFvmPartition(fd)) != ZX_OK) {
        return rc;
    }
    if ((rc = cmdline->Confirm()) != ZX_OK || (rc = ReopenWritable(&fd)) != ZX_OK) {
        return rc;
    }
    if ((res = ioctl_block_fvm_extend(fd, &request)) < 0) {
        fprintf(stderr, "ioctl_block_fvm_extend failed: %s\n", zx_status_get_string(rc));
        rc = static_cast<zx_status_t>(res);
        return rc;
    }
    printf("partition extended\n");
    return ZX_OK;
}

zx_status_t Shrink::Run() {
    zx_status_t rc;
    ssize_t res;
    BlkCtl* cmdline = this->cmdline();

    const char* dev;
    int fd;
    extend_request_t request;
    if ((rc = cmdline->GetStrArg("device", &dev)) != ZX_OK ||
        (rc = cmdline->GetNumArg("start", &request.offset)) != ZX_OK ||
        (rc = cmdline->GetNumArg("length", &request.length)) != ZX_OK ||
        (rc = cmdline->ArgsDone()) != ZX_OK || (rc = OpenReadable(dev, &fd)) != ZX_OK ||
        (rc = CheckFvmPartition(fd)) != ZX_OK) {
        return rc;
    }
    if ((rc = cmdline->Confirm()) != ZX_OK || (rc = ReopenWritable(&fd)) != ZX_OK) {
        return rc;
    }
    if ((res = ioctl_block_fvm_shrink(fd, &request)) < 0) {
        rc = static_cast<zx_status_t>(res);
        fprintf(stderr, "ioctl_block_fvm_shrink failed: %s\n", zx_status_get_string(rc));
        return rc;
    }
    printf("partition shrunk\n");
    return ZX_OK;
}

zx_status_t Remove::Run() {
    zx_status_t rc;
    ssize_t res;
    BlkCtl* cmdline = this->cmdline();

    const char* dev;
    int fd;
    if ((rc = cmdline->GetStrArg("device", &dev)) != ZX_OK || (rc = cmdline->ArgsDone()) != ZX_OK ||
        (rc = OpenReadable(dev, &fd)) != ZX_OK || (rc = CheckFvmPartition(fd)) != ZX_OK) {
        return rc;
    }
    if ((rc = cmdline->Confirm()) != ZX_OK || (rc = ReopenWritable(&fd)) != ZX_OK) {
        return rc;
    }
    if ((res = ioctl_block_fvm_destroy_partition(fd)) < 0) {
        rc = static_cast<zx_status_t>(res);
        fprintf(stderr, "ioctl_block_fvm_destroy_partition failed: %s\n", zx_status_get_string(rc));
        return rc;
    }
    printf("partition removed\n");
    return ZX_OK;
}

zx_status_t Destroy::Run() {
    zx_status_t rc;
    ssize_t res;
    BlkCtl* cmdline = this->cmdline();

    const char* dev;
    int fd;
    if ((rc = cmdline->GetStrArg("device", &dev)) != ZX_OK || (rc = cmdline->ArgsDone()) != ZX_OK ||
        (rc = OpenReadable(dev, &fd)) != ZX_OK) {
        return rc;
    }
    char path[PATH_MAX];
    constexpr const char* suffix = "/fvm";
    ZX_DEBUG_ASSERT(strlen(suffix) < sizeof(path));
    size_t path_max = sizeof(path) - (strlen(suffix) + 1);
    if ((res = ioctl_device_get_topo_path(fd, path, path_max)) < 0) {
        rc = static_cast<zx_status_t>(res);
        fprintf(stderr, "failed to get topological path: %s\n", zx_status_get_string(rc));
        return rc;
    }
    strcat(path, suffix); // Safe to due to size limit above
    fbl::unique_fd fvm_fd(open(path, O_RDONLY));
    if ((rc = CheckFvmVolume(fvm_fd.get())) != ZX_OK) {
        return rc;
    }
    fvm_fd.reset();
    if ((rc = cmdline->Confirm()) != ZX_OK || (rc = ReopenWritable(&fd)) != ZX_OK) {
        return rc;
    }
    if ((rc = fvm_destroy(devname())) != ZX_OK) {
        fprintf(stderr, "fvm_destroy failed\n");
        return rc;
    }
    if ((res = ioctl_block_rr_part(fd)) < 0) {
        rc = static_cast<zx_status_t>(res);
        fprintf(stderr, "failed to unbind FVM driver: %s\n", zx_status_get_string(rc));
        return rc;
    }
    printf("FVM volume metadata destroyed\n");
    return ZX_OK;
}

} // namespace fvm
} // namespace blkctl
