// 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 <limits.h>
#include <stdint.h>

namespace {

enum class FsTestType {
    // The partition may appear as any generic block device
    kNormal,

    // The partition should appear on top of a resizable
    // FVM device
    kFvm,
};

enum class FsTestState {
    kInit, // Just created, waiting to be initialized.
    kMinimal, // Initialized in a minimal state, i.e. ramdisk only.
    kRunning, // Initialized and ready to start testing.
    kComplete, // Indicates that the test has completed.
    kError, // Indicates that an error has occurred.
};

class BlobfsTest {
public:
    BlobfsTest(FsTestType type) : type_(type) {}
    ~BlobfsTest();

    // Creates a ramdisk, formats it, and mounts it at a mount point.
    // |state| indicates the intended state once initialization is complete.
    // This value must be either kMinimal or kRunning.
    // If |state| is kMinimal, the mkfs and mount methods will be skipped.
    bool Init(FsTestState state = FsTestState::kRunning);

    // Unmounts and remounts the blobfs partition.
    bool Remount();

    // Forcibly unmounts and remounts the blobfs partition, regardless of the current test state.
    // If the partition is successfully remounted, the test is restored to a kRunning state.
    // If |fsck_result| is not nullptr, fsck is run before remount and |fsck_result| is set to
    // the result.
    bool ForceRemount(zx_status_t* fsck_result = nullptr);

    // Unmounts a blobfs, runs fsck, and removes the backing ramdisk device.
    // If the state_ is not kRunning, the umount and fsck methods will be skipped.
    bool Teardown();

    FsTestType GetType() const {
        return type_;
    }

    int GetFd() const {
        return open(ramdisk_path_, O_RDWR);
    }

    off_t GetDiskSize() const {
        return blk_size_ * blk_count_;
    }

    uint64_t GetBlockSize() const {
        return blk_size_;
    }

    uint64_t GetBlockCount() const {
        return blk_count_;
    }

    // Returns the full device path of blobfs.
    bool GetDevicePath(char* path, size_t len) const;

    // Given a new disk size, updates the block count. Block size doesn't change.
    bool SetBlockCount(uint64_t block_count) {
        BEGIN_HELPER;
        ASSERT_EQ(state_, FsTestState::kInit);
        blk_count_ = block_count;
        END_HELPER;
    }

    // Sets readonly to |readonly|, defaulting to true.
    void SetReadOnly(bool read_only) {
        read_only_ = read_only;
    }

    // Determine if the mounted filesystem should have output to stdio.
    void SetStdio(bool stdio) {
        stdio_ = stdio;
    }

    // Reset to initial state, given that the test was successfully torn down.
    bool Reset() {
        BEGIN_HELPER;
        ASSERT_EQ(state_, FsTestState::kComplete);
        state_ = FsTestState::kInit;
        END_HELPER;
    }

    // Forcibly resets a running test by destroying and recreating the Blobfs partition.
    bool ForceReset();

    // Sleeps or wakes the ramdisk underlying the blobfs partition, depending on its current state.
    bool ToggleSleep(uint64_t blk_count = 0);

    // Returns the current total transaction block count from the underlying ramdisk.
    bool GetRamdiskCount(uint64_t* blk_count) const;

    // Checks info of mounted blobfs.
    //
    // Returns total number of bytes available as |total_bytes|.
    // Returns total number of used bytes as |used_bytes|.
    bool CheckInfo(uint64_t* total_bytes = nullptr, uint64_t* used_bytes = nullptr);

private:
    // Mounts the blobfs partition.
    bool Mount();

    FsTestType type_;
    FsTestState state_ = FsTestState::kInit;
    uint64_t blk_size_ = 512;
    uint64_t blk_count_ = 1 << 20;
    char ramdisk_path_[PATH_MAX];
    char fvm_path_[PATH_MAX];
    bool read_only_ = false;
    bool asleep_ = false;
    bool stdio_ = true;
};

// Mock journal implementation which can be used to test JournalEntry / JournalProcessor
// functionality.
class FakeJournal : public blobfs::JournalBase {
public:
    FakeJournal() : readonly_(false), capacity_(0) {}

    void SendSignal(zx_status_t status) final {
        if (status != ZX_OK) {
            readonly_ = true;
        }
    }

    fbl::unique_ptr<blobfs::WritebackWork> CreateDefaultWork() {
        return CreateWork();
    }

    fbl::unique_ptr<blobfs::WritebackWork> CreateBufferedWork(size_t block_count) {
        fbl::unique_ptr<blobfs::WritebackWork> work = CreateWork();
        work->Enqueue(1, 0, 0, block_count);
        work->SetBuffer(2);
        return fbl::move(work);
    }

private:
    size_t GetCapacity() const final {
        return capacity_;
    }

    bool IsReadOnly() const final {
        return readonly_;
    }

    fbl::unique_ptr<blobfs::WritebackWork> CreateWork() final {
        return fbl::make_unique<blobfs::WritebackWork>(nullptr, nullptr);
    }

    // The following functions are no-ops, and only exist so they can be called by the
    // JournalProcessor.
    void PrepareBuffer(blobfs::JournalEntry* entry) final {}
    void PrepareDelete(blobfs::JournalEntry* entry, blobfs::WritebackWork* work) final {}
    zx_status_t EnqueueEntryWork(fbl::unique_ptr<blobfs::WritebackWork> work) final {
        return ZX_OK;
    }

    bool readonly_;
    size_t capacity_;
};

}  // namespace
