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

#pragma once

#include <stdint.h>
#include <stdio.h>
#include <unistd.h>

#include <fbl/function.h>
#include <fbl/string.h>
#include <fbl/vector.h>
#include <fs-management/mount.h>
#include <fvm/format.h>
#include <lib/zx/time.h>
#include <ramdevice-client/ramdisk.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

// Macro for printing more information in error logs.
// "[File:Line] Error(error_name): Message\n"
#define LOG_ERROR(error_code, msg_fmt, ...)        \
    fprintf(stderr, "[%s:%d] Error(%s): " msg_fmt, \
            __FILE__, __LINE__, zx_status_get_string(error_code), ##__VA_ARGS__)

// Macro for printing more information in stdout.
// "[File:Line] Info: Message\n"
#define LOG_INFO(msg_fmt, ...)                \
    fprintf(stdout, "[%s:%d] Info: " msg_fmt, \
            __FILE__, __LINE__, ##__VA_ARGS__)

namespace fs_test_utils {

constexpr size_t kPathSize = PATH_MAX;

constexpr size_t kFvmBlockSize = fvm::kBlockSize;

// TODO(gevalentno): when ZX-2013 is resolved, make MemFs setup and teardown
// part of the test fixture and remove RunWithMemFs.
// Workaround that provides a MemFs per process, since it cannot be unbinded
// from the process namespace yet.
int RunWithMemFs(const fbl::Function<int()>& main_fn);

// Available options for the test fixture.
//
// Note: use_ramdisk and block_device_path are mutually exclusive.
struct FixtureOptions {

    static FixtureOptions Default(disk_format_t format) {
        FixtureOptions options;
        options.use_ramdisk = true;
        options.ramdisk_block_size = 512;
        options.ramdisk_block_count = zx_system_get_physmem() / (2 * options.ramdisk_block_size);
        options.use_fvm = false;
        options.fvm_slice_size = kFvmBlockSize * (2 << 10);
        options.fs_type = format;
        options.seed = static_cast<unsigned int>(zx::ticks::now().get());
        return options;
    }

    // Returns true if the options are valid.
    // When invalid |err_string| will be populated with a human readable error description.
    bool IsValid(fbl::String* err_description) const;

    // Path to the block device to use.
    fbl::String block_device_path = "";

    // If true a ramdisk will be created and shared for the test.
    bool use_ramdisk = false;

    // Number of blocks the ramdisk will contain.
    size_t ramdisk_block_count = 0;

    // Size of the blocks the ramdisk will have.
    size_t ramdisk_block_size = 0;

    // If true an fvm will be mounted on the device, and the filesystem will be
    // mounted on top of a fresh partition.
    bool use_fvm = false;

    // Size of each slice of the created fvm.
    size_t fvm_slice_size = 0;

    // Type of filesystem to mount.
    disk_format_t fs_type;

    // Format the device device with the given |fs_type|. This is useful
    // when a test requires a block_device(and fvm) for tests.
    bool fs_format = true;

    // Mount the device in |Fixture::fs_path()|. Format is auto detected.
    bool fs_mount = true;

    // Seed for pseudo random number generator.
    unsigned int seed = 0;
};

// Provides a base fixture for File system tests.
// In main(a.k.a run_all_unittests):
//
// RunWithMemFs([argc, argv] () {  // Sets up then cleans up Local MemFs.
//   return run_all_unittests(argc, argv) ? 0: 1;
// }
class Fixture {
public:
    Fixture() = delete;
    explicit Fixture(const FixtureOptions& options);
    Fixture(const Fixture&) = delete;
    Fixture(Fixture&&) = delete;
    Fixture& operator=(const Fixture&) = delete;
    Fixture& operator=(Fixture&&) = delete;
    ~Fixture();

    // Returns the options used by this fixture.
    const FixtureOptions& options() const {
        return options_;
    }

    // Returns the path to the block device hosting the FS.
    const fbl::String& block_device_path() const {
        return block_device_path_;
    }

    // Returns the path to the FVM partition created for the block device
    // hosting the FS. Will return empty if !options_.use_fvm.
    const fbl::String& partition_path() const {
        return partition_path_;
    }

    // Returns either the block_device path or partition_path if using fvm.
    const fbl::String& GetFsBlockDevice() const {
        return (options_.use_fvm) ? partition_path_ : block_device_path_;
    }

    // Returns the path where the filesystem was mounted.
    const fbl::String& fs_path() const {
        return fs_path_;
    }

    // Returns a seed to be used along the test, for rand_r calls.
    unsigned int* mutable_seed() {
        return &seed_;
    }

    // Unmounts the FS from fs_path.
    zx_status_t Umount();

    // Mounts the FsBlockDevice into fs_path.
    zx_status_t Mount();

    // Umounts and then Mounts the device.
    zx_status_t Remount() {
        zx_status_t res = Umount();
        if (res != ZX_OK) {
            return res;
        }
        res = Mount();
        return res;
    }

    // Checks the disk with fsck.
    zx_status_t Fsck() const;

    // Format (or reformat) the device.
    zx_status_t Format() const;

    // Sets up MemFs and Ramdisk, allocating resources for the tests.
    zx_status_t SetUpTestCase();

    // Formats the block device with the required type, creates a fvm, and mounts
    // the fs.
    zx_status_t SetUp();

    // Cleans up the block device by reformatting it, destroys the fvm and
    // unmounts the fs.
    zx_status_t TearDown();

    // Destroys the ramdisk, MemFs will die with the process. This should be
    // called after all tests finished execution to free resources.
    zx_status_t TearDownTestCase();

private:
    FixtureOptions options_;

    // State of the resources allocated by the fixture.
    enum class ResourceState {
        kUnallocated,
        kAllocated,
        kFreed,
    };

    // The ramdisk, if it exists.
    ramdisk_client_t* ramdisk_ = nullptr;

    // Path to the block device hosting the mounted FS.
    fbl::String block_device_path_;

    // When using fvm, the FS will be mounted here.
    fbl::String partition_path_;

    // The root path where FS is mounted.
    fbl::String fs_path_;

    unsigned int seed_;

    // Keep track of the resource allocation during the setup teardown process,
    // to avoid leaks, or unnecessary errors when trying to free resources, that
    // may have never been allocated in first place.
    ResourceState fs_state_ = ResourceState::kUnallocated;
    ResourceState fvm_state_ = ResourceState::kUnallocated;
    ResourceState ramdisk_state_ = ResourceState::kUnallocated;
};

} // namespace fs_test_utils
