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

#include <fbl/auto_call.h>
#include <fbl/function.h>
#include <fbl/string.h>
#include <fbl/unique_fd.h>
#include <fs-management/ramdisk.h>
#include <fs-test-utils/fixture.h>
#include <unittest/unittest.h>
#include <zircon/device/block.h>
#include <zircon/syscalls.h>

namespace fs_test_utils {
namespace {

zx_status_t
GetBlockDeviceInfo(const fbl::String& block_device_path, block_info_t* blk_info) {
    fbl::unique_fd fd(open(block_device_path.c_str(), O_RDONLY));
    ssize_t result = ioctl_block_get_info(fd.get(), blk_info);
    if (result < 0) {
        return static_cast<zx_status_t>(result);
    }
    return ZX_OK;
}

bool IsValidBlockDeviceOnlyTrue() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    options.block_device_path = "some_block_device";
    ASSERT_TRUE(options.IsValid(&err_str), err_str.c_str());
    ASSERT_TRUE(err_str.empty());
    END_TEST;
}

bool IsValidUseRamdiskTrue() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    options.use_ramdisk = true;
    options.ramdisk_block_size = 512;
    options.ramdisk_block_count = 1;
    ASSERT_TRUE(options.IsValid(&err_str), err_str.c_str());
    ASSERT_TRUE(err_str.empty());
    END_TEST;
}

bool IsValidUseFvmTrue() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    fbl::String err_str;
    options.use_fvm = true;
    options.fvm_slice_size = kFvmBlockSize;
    ASSERT_TRUE(options.IsValid(&err_str), err_str.c_str());
    ASSERT_TRUE(err_str.empty());
    END_TEST;
}

bool IsValidEmptyIsFalse() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

bool IsValidDefaultIsTrue() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    fbl::String err_str;
    ASSERT_TRUE(options.IsValid(&err_str));
    ASSERT_TRUE(err_str.empty());
    END_TEST;
}

bool IsValidBlockAndRamdiskSetIsFalse() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    options.block_device_path = "some_block_device";
    options.use_ramdisk = true;
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

bool IsValidRamdiskBlockCountIsZeroFalse() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    options.use_ramdisk = true;
    options.ramdisk_block_count = 0;
    options.ramdisk_block_size = 512;
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

bool IsValidRamdiskBlockSizeIsZeroFalse() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    options.use_ramdisk = true;
    options.ramdisk_block_count = 10;
    options.ramdisk_block_size = 0;
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

bool IsValidFvmSlizeSizeIsZeroFalse() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    fbl::String err_str;
    options.use_fvm = true;
    options.fvm_slice_size = 0;
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

bool IsValidFvmSlizeSizeIsNotMultipleOfFvmBlockSizeFalse() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    fbl::String err_str;
    options.use_fvm = true;
    options.fvm_slice_size = kFvmBlockSize + 3;
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

bool IsValidNoBlockDeviceFalse() {
    BEGIN_TEST;
    FixtureOptions options;
    fbl::String err_str;
    options.block_device_path = "";
    ASSERT_FALSE(options.IsValid(&err_str));
    ASSERT_FALSE(err_str.empty());
    END_TEST;
}

BEGIN_TEST_CASE(FixtureOptionsTests);
RUN_TEST(IsValidBlockDeviceOnlyTrue);
RUN_TEST(IsValidUseRamdiskTrue);
RUN_TEST(IsValidUseFvmTrue);
RUN_TEST(IsValidDefaultIsTrue);
RUN_TEST(IsValidEmptyIsFalse);
RUN_TEST(IsValidNoBlockDeviceFalse);
RUN_TEST(IsValidBlockAndRamdiskSetIsFalse);
RUN_TEST(IsValidRamdiskBlockCountIsZeroFalse);
RUN_TEST(IsValidRamdiskBlockSizeIsZeroFalse);
RUN_TEST(IsValidFvmSlizeSizeIsZeroFalse);
RUN_TEST(IsValidFvmSlizeSizeIsNotMultipleOfFvmBlockSizeFalse);
END_TEST_CASE(FixtureOptionsTests);

bool RamdiskSetupAndCleanup() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_BLOBFS);
    Fixture fixture(options);
    fixture.SetUpTestCase();
    ASSERT_TRUE(!fixture.block_device_path().empty());
    block_info_t ramdisk_info;
    ASSERT_EQ(GetBlockDeviceInfo(fixture.block_device_path(), &ramdisk_info), ZX_OK);
    ASSERT_EQ(ramdisk_info.block_count, options.ramdisk_block_count);
    ASSERT_EQ(ramdisk_info.block_size, options.ramdisk_block_size);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    fbl::unique_fd ramdisk_fd(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_FALSE(ramdisk_fd);
    END_TEST;
}

bool DiskIsFormattedCorrectlyNoFvm() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    // Check device format.
    fbl::unique_fd blk_fd(open(fixture.GetFsBlockDevice().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    disk_format_t actual = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual, DISK_FORMAT_MINFS);
    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    // Verify nothing is mounted anymore.
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_ERR_NOT_FOUND);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool DiskAndFvmAreFormattedCorrectly() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.use_fvm = true;
    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    // Check device format.
    fbl::unique_fd blk_fd(open(fixture.GetFsBlockDevice().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    disk_format_t actual = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual, DISK_FORMAT_MINFS);

    fbl::unique_fd fvm_blk_fd(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(fvm_blk_fd);
    disk_format_t fvm_actual = detect_disk_format(fvm_blk_fd.get());
    ASSERT_EQ(fvm_actual, DISK_FORMAT_FVM);

    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    // Verify nothing is mounted anymore.
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_ERR_NOT_FOUND);

    ASSERT_TRUE(fvm_blk_fd);
    fvm_actual = detect_disk_format(fvm_blk_fd.get());
    ASSERT_EQ(fvm_actual, DISK_FORMAT_UNKNOWN);

    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool UseBlockDeviceIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.use_ramdisk = false;

    // Create a Ramdisk which will be passed as the 'block_device'.
    char block_device[kPathSize];
    ASSERT_EQ(create_ramdisk(options.ramdisk_block_size,
                             options.ramdisk_block_count, block_device),
              ZX_OK);
    options.block_device_path = block_device;

    auto clean_up = fbl::MakeAutoCall([&options]() {
        destroy_ramdisk(options.block_device_path.c_str());
    });

    mkfs_options_t mkfs_options = default_mkfs_options;
    ASSERT_EQ(mkfs(options.block_device_path.c_str(), DISK_FORMAT_BLOBFS,
                   launch_stdio_sync, &mkfs_options),
              ZX_OK);

    Fixture fixture(options);

    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    EXPECT_TRUE(options.block_device_path == fixture.block_device_path());
    EXPECT_TRUE(options.block_device_path == fixture.GetFsBlockDevice());
    fbl::unique_fd blk_fd(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    disk_format_t actual_format = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_BLOBFS);

    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    blk_fd.reset(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    actual_format = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_MINFS);

    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    blk_fd.reset(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    actual_format = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_MINFS);

    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool UseBlockDeviceWithFvmIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.use_ramdisk = false;
    options.use_fvm = true;

    // Create a Ramdisk which will be passed as the 'block_device'.
    char block_device[kPathSize];
    ASSERT_EQ(create_ramdisk(options.ramdisk_block_size,
                             options.ramdisk_block_count, block_device),
              ZX_OK);
    options.block_device_path = block_device;

    auto clean_up = fbl::MakeAutoCall([&options]() {
        destroy_ramdisk(options.block_device_path.c_str());
    });

    mkfs_options_t mkfs_options = default_mkfs_options;
    ASSERT_EQ(mkfs(options.block_device_path.c_str(), DISK_FORMAT_BLOBFS,
                   launch_stdio_sync, &mkfs_options),
              ZX_OK);

    Fixture fixture(options);

    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    EXPECT_TRUE(options.block_device_path == fixture.block_device_path());
    EXPECT_TRUE(fixture.GetFsBlockDevice().empty());
    fbl::unique_fd blk_fd(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    disk_format_t actual_format = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_BLOBFS);

    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    blk_fd.reset(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    actual_format = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_FVM);

    blk_fd.reset(open(fixture.GetFsBlockDevice().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    actual_format = detect_disk_format(blk_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_MINFS);

    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    blk_fd.reset(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(blk_fd);
    actual_format = detect_disk_format(blk_fd.get());
    // Destroying the FVM should leave this in unknown format.
    ASSERT_EQ(actual_format, DISK_FORMAT_UNKNOWN);

    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool SkipFormatIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.use_ramdisk = false;
    options.fs_format = false;

    // Create a Ramdisk which will be passed as the 'block_device'.
    char block_device[kPathSize];
    ASSERT_EQ(create_ramdisk(options.ramdisk_block_size,
                             options.ramdisk_block_count, block_device),
              ZX_OK);
    options.block_device_path = block_device;

    auto clean_up = fbl::MakeAutoCall([&options]() {
        destroy_ramdisk(options.block_device_path.c_str());
    });

    mkfs_options_t mkfs_options = default_mkfs_options;
    ASSERT_EQ(mkfs(options.block_device_path.c_str(), DISK_FORMAT_BLOBFS,
                   launch_stdio_sync, &mkfs_options),
              ZX_OK);

    Fixture fixture(options);

    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    EXPECT_TRUE(options.block_device_path == fixture.block_device_path());
    EXPECT_TRUE(options.block_device_path == fixture.GetFsBlockDevice());
    fbl::unique_fd block_fd(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(block_fd);
    disk_format_t actual_format = detect_disk_format(block_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_BLOBFS);

    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    block_fd.reset(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(block_fd);
    actual_format = detect_disk_format(block_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_BLOBFS);

    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    block_fd.reset(open(fixture.block_device_path().c_str(), O_RDONLY));
    ASSERT_TRUE(block_fd);
    actual_format = detect_disk_format(block_fd.get());
    ASSERT_EQ(actual_format, DISK_FORMAT_BLOBFS);

    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool SkipMountIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.fs_mount = false;

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);

    // Verify nothing is mounted anymore.
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_ERR_NOT_FOUND);
    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool MountIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.fs_mount = false;

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_ERR_NOT_FOUND);
    ASSERT_EQ(fixture.Mount(), ZX_OK);
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_OK);

    // Since we need to try to umount to verify if the device is mounted,
    // the fixture still sees the device as mounted, so it will try to umount
    // and fail with not found, which is ok.
    ASSERT_EQ(fixture.TearDown(), ZX_ERR_NOT_FOUND);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool UmountIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.fs_mount = true;

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    ASSERT_EQ(fixture.Umount(), ZX_OK);
    // Verify nothing is mounted anymore.
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_ERR_NOT_FOUND);
    ASSERT_EQ(fixture.TearDown(), ZX_OK);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

bool RemountIsOk() {
    BEGIN_TEST;
    FixtureOptions options = FixtureOptions::Default(DISK_FORMAT_MINFS);
    options.fs_mount = true;

    Fixture fixture(options);
    ASSERT_EQ(fixture.SetUpTestCase(), ZX_OK);
    ASSERT_EQ(fixture.SetUp(), ZX_OK);
    ASSERT_EQ(fixture.Remount(), ZX_OK);
    ASSERT_EQ(umount(fixture.fs_path().c_str()), ZX_OK);
    // Teardown will return this error because we manually umount the underlying
    ASSERT_EQ(fixture.TearDown(), ZX_ERR_NOT_FOUND);
    ASSERT_EQ(fixture.TearDownTestCase(), ZX_OK);
    END_TEST;
}

BEGIN_TEST_CASE(FixtureTest);
RUN_TEST(RamdiskSetupAndCleanup);
RUN_TEST(DiskIsFormattedCorrectlyNoFvm);
RUN_TEST(DiskAndFvmAreFormattedCorrectly);
RUN_TEST(UseBlockDeviceIsOk);
RUN_TEST(UseBlockDeviceWithFvmIsOk);
RUN_TEST(SkipFormatIsOk);
RUN_TEST(SkipMountIsOk);
RUN_TEST(MountIsOk);
RUN_TEST(UmountIsOk);
RUN_TEST(RemountIsOk);
END_TEST_CASE(FixtureTest);

} // namespace
} // namespace fs_test_utils
