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

#include <fs-management/mount.h>

#include <errno.h>
#include <fcntl.h>
#include <new>
#include <string.h>
#include <unistd.h>

#include <fbl/unique_fd.h>
#include <fbl/unique_ptr.h>
#include <fbl/vector.h>
#include <lib/fdio/limits.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/vfs.h>
#include <lib/zx/channel.h>
#include <zircon/compiler.h>
#include <zircon/device/vfs.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>

namespace {

zx_status_t FsckNativeFs(const char* device_path, const fsck_options_t* options,
                         LaunchCallback cb, const char* cmd_path) {
    fbl::unique_fd device_fd;
    device_fd.reset(open(device_path, O_RDWR));
    if (!device_fd) {
        fprintf(stderr, "Failed to open device\n");
        return ZX_ERR_BAD_STATE;
    }
    zx::channel block_device;
    zx_status_t status = fdio_get_service_handle(device_fd.release(),
                                                 block_device.reset_and_get_address());
    if (status != ZX_OK) {
        return status;
    }

    fbl::Vector<const char*> argv;
    argv.push_back(cmd_path);
    if (options->verbose) {
        argv.push_back("-v");
    }
    if (options->apply_journal) {
        argv.push_back("-j");
    }
    // TODO(smklein): Add support for modify, force flags. Without them,
    // we have "never_modify=true" and "force=true" effectively on by default.
    argv.push_back("fsck");
    argv.push_back(nullptr);

    zx_handle_t hnd = block_device.release();
    uint32_t id = FS_HANDLE_BLOCK_DEVICE_ID;
    auto argc = static_cast<int>(argv.size() - 1);
    status = static_cast<zx_status_t>(cb(argc, argv.get(), &hnd, &id, 1));
    return status;
}

zx_status_t FsckFat(const char* device_path, const fsck_options_t* options,
                    LaunchCallback cb) {
    fbl::Vector<const char*> argv;
    argv.push_back("/boot/bin/fsck-msdosfs");
    if (options->never_modify) {
        argv.push_back("-n");
    } else if (options->always_modify) {
        argv.push_back("-y");
    }
    if (options->force) {
        argv.push_back("-f");
    }
    argv.push_back(device_path);
    argv.push_back(nullptr);
    auto argc = static_cast<int>(argv.size() - 1);
    zx_status_t status = static_cast<zx_status_t>(cb(argc, argv.get(), nullptr, nullptr, 0));
    return status;
}

}  // namespace

zx_status_t fsck(const char* device_path, disk_format_t df,
                 const fsck_options_t* options, LaunchCallback cb) {
    switch (df) {
    case DISK_FORMAT_MINFS:
        return FsckNativeFs(device_path, options, cb, "/boot/bin/minfs");
    case DISK_FORMAT_FAT:
        return FsckFat(device_path, options, cb);
    case DISK_FORMAT_BLOBFS:
        return FsckNativeFs(device_path, options, cb, "/boot/bin/blobfs");
    default:
        return ZX_ERR_NOT_SUPPORTED;
    }
}
