// Copyright 2019 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 "src/storage/fvm/driver/vpartition_manager.h"

#include <lib/inspect/cpp/hierarchy.h>
#include <lib/inspect/cpp/reader.h>

#include <vector>

#include <zxtest/zxtest.h>

#include "src/storage/fvm/driver/vpartition.h"
#include "src/storage/fvm/format.h"
#include "src/storage/fvm/metadata.h"

namespace fvm {

constexpr size_t kFvmSliceSize = 8 * kBlockSize;
constexpr size_t kDiskSize = 64 * kBlockSize;
constexpr uint32_t kBlocksPerSlice = 128;

// Provides a very simple ramdisk-like interface where we can track trim operations
class FakeBlockDevice : public ddk::BlockImplProtocol<FakeBlockDevice> {
 public:
  static constexpr uint32_t kBlockSize = 512;

  FakeBlockDevice() : proto_({&block_impl_protocol_ops_, this}) { data_.resize(kDiskSize); }

  block_impl_protocol_t* proto() { return &proto_; }

  // Access to the underlying data for tests to provide data or validate writes.
  const std::vector<uint8_t>& data() const { return data_; }
  std::vector<uint8_t>& data() { return data_; }

  // Block protocol:
  void BlockImplQuery(block_info_t* out_info, size_t* out_block_op_size) {
    *out_info = {};
    out_info->block_size = kBlockSize;
    out_info->block_count = kDiskSize / out_info->block_size;
    out_info->max_transfer_size = BLOCK_MAX_TRANSFER_UNBOUNDED;
    *out_block_op_size = sizeof(block_op_t);
  }

  void BlockImplQueue(block_op_t* operation, block_impl_queue_callback completion_cb,
                      void* cookie) {
    zx_status_t result = ZX_OK;
    switch (operation->command) {
      case BLOCK_OP_READ:
        // Read from device, write to VMO.
        if ((operation->rw.offset_dev + operation->rw.length) * kBlockSize <= data_.size()) {
          result = zx_vmo_write(operation->rw.vmo, &data_[operation->rw.offset_dev * kBlockSize],
                                operation->rw.offset_vmo * kBlockSize,
                                operation->rw.length * kBlockSize);
        } else {
          result = ZX_ERR_OUT_OF_RANGE;
        }
        break;
      case BLOCK_OP_WRITE:
        // Write to device, read from VMO.
        if ((operation->rw.offset_dev + operation->rw.length) * kBlockSize <= data_.size()) {
          result =
              zx_vmo_read(operation->rw.vmo, &data_[operation->rw.offset_dev * kBlockSize],
                          operation->rw.offset_vmo * kBlockSize, operation->rw.length * kBlockSize);
        } else {
          result = ZX_ERR_OUT_OF_RANGE;
        }
        break;
      case BLOCK_OP_TRIM:
        num_trim_calls_++;
        last_trim_length_ += operation->trim.length;
        break;
    }
    completion_cb(cookie, result, operation);
  }

  int num_trim_calls() const { return num_trim_calls_; }
  uint32_t last_trim_length() const { return last_trim_length_; }

 private:
  block_impl_protocol_t proto_;
  int num_trim_calls_ = 0;
  uint32_t last_trim_length_ = 0;

  std::vector<uint8_t> data_;
};

TEST(VPartitionManager, TrivialLifetime) {
  FakeBlockDevice block_device;
  block_info_t info;
  size_t block_op_size;
  block_device.BlockImplQuery(&info, &block_op_size);
  VPartitionManager device(nullptr, info, block_op_size, block_device.proto());

  VPartition partition(&device, 1, block_op_size);
}

// Initializes a block device containing an FVM header with one partition with the given oldest
// revision.
template <uint64_t oldest_minor_version>
class VPartitionManagerTestAtRevision : public zxtest::Test {
 public:
  void SetUp() override {
    block_info_t info;
    block_device_.BlockImplQuery(&info, &block_op_size_);

    // Generate the FVM partition information for the initial device state. This contains no
    // partitions or allocated slices.
    Header header = Header::FromDiskSize(kMaxUsablePartitions, kDiskSize, kFvmSliceSize);
    header.oldest_minor_version = oldest_minor_version;
    auto metadata_or = Metadata::Synthesize(header, nullptr, 0u, nullptr, 0u);
    ASSERT_TRUE(metadata_or.is_ok());

    // Write the FVM data to the device.
    ASSERT_LT(metadata_or.value().Get()->size(), block_device_.data().size());
    memcpy(block_device_.data().data(), metadata_or.value().Get()->data(),
           metadata_or.value().Get()->size());

    device_ =
        std::make_unique<VPartitionManager>(nullptr, info, block_op_size_, block_device_.proto());
    device_->Load();

    ASSERT_EQ(kBlocksPerSlice, kFvmSliceSize / info.block_size);
  }

  // Returns a copy of the FVM metadata written to the block device.
  zx::status<Metadata> GetMetadata() const {
    // Need to look at the header to tell how big the metadata will be.
    Header header;
    if (block_device_.data().size() < sizeof(Header))
      return zx::error(ZX_ERR_BUFFER_TOO_SMALL);
    memcpy(&header, block_device_.data().data(), sizeof(Header));

    // Now copy the full metadata out.
    size_t metadata_size = header.GetMetadataAllocatedBytes();
    if (block_device_.data().size() < metadata_size * 2)
      return zx::error(ZX_ERR_BUFFER_TOO_SMALL);
    auto metadata_a_buffer = std::make_unique<uint8_t[]>(metadata_size);
    auto metadata_b_buffer = std::make_unique<uint8_t[]>(metadata_size);
    memcpy(metadata_a_buffer.get(), block_device_.data().data(), metadata_size);
    memcpy(metadata_b_buffer.get(),
           block_device_.data().data() + header.GetMetadataAllocatedBytes(), metadata_size);

    return Metadata::Create(
        std::make_unique<HeapMetadataBuffer>(std::move(metadata_a_buffer), metadata_size),
        std::make_unique<HeapMetadataBuffer>(std::move(metadata_b_buffer), metadata_size));
  }

  // Create a partition and returns it on success.
  zx::status<std::unique_ptr<VPartition>> AllocatePartition(const std::string& name = "name",
                                                            uint64_t slices = 1u) {
    static int next_id = 1;

    // Generates a test-unique id for the type and instance.
    fuchsia_hardware_block_partition::wire::Guid type_guid{.value = {0}};
    memcpy(type_guid.value.data(), &next_id, sizeof(int));
    next_id++;

    fuchsia_hardware_block_partition::wire::Guid instance_guid{.value = {0}};
    memcpy(instance_guid.value.data(), &next_id, sizeof(int));
    next_id++;

    return device_->AllocatePartition(slices, type_guid, instance_guid,
                                      fidl::StringView::FromExternal(name), 0);
  }

 protected:
  FakeBlockDevice block_device_;
  std::unique_ptr<VPartitionManager> device_;

  size_t block_op_size_ = 0;
};

using VPartitionManagerTest = VPartitionManagerTestAtRevision<kCurrentMinorVersion>;

// Verifies that simple TRIM commands are forwarded to the underlying device.
TEST_F(VPartitionManagerTest, QueueTrimOneSlice) {
  auto partition_or = AllocatePartition();
  ASSERT_TRUE(partition_or.is_ok());

  const uint32_t kOperationLength = 20;

  block_op_t op = {};
  op.trim.command = BLOCK_OP_TRIM;
  op.trim.length = kOperationLength;
  op.trim.offset_dev = kBlocksPerSlice / 2;

  partition_or.value()->BlockImplQueue(
      &op, [](void*, zx_status_t status, block_op_t*) {}, nullptr);
  EXPECT_EQ(1, block_device_.num_trim_calls());
  EXPECT_EQ(kOperationLength, block_device_.last_trim_length());
}

// Verifies that TRIM commands that span slices are forwarded to the underlying device.
TEST_F(VPartitionManagerTest, QueueTrimConsecutiveSlices) {
  // Ideally this should use AllocatePartition to have the VPartitionManager create the partition in
  // the correct way. This test is suspicious because pslice values aren't supposed to be zero whic
  // is used below, and haveing the VPartitionManager create the partition makes this test code
  // fail. This test should be revisited.
  auto partition = std::make_unique<VPartition>(device_.get(), 1, block_op_size_);

  const uint32_t kOperationLength = 20;
  partition->SliceSetUnsafe(0, 0);  // Suspicious value, see above.
  partition->SliceSetUnsafe(1, 1);

  block_op_t op = {};
  op.trim.command = BLOCK_OP_TRIM;
  op.trim.length = kOperationLength;
  op.trim.offset_dev = kBlocksPerSlice - kOperationLength / 2;

  partition->BlockImplQueue(
      &op, [](void*, zx_status_t status, block_op_t*) {}, nullptr);
  EXPECT_EQ(1, block_device_.num_trim_calls());
  EXPECT_EQ(kOperationLength, block_device_.last_trim_length());
}

// Verifies that TRIM commands spanning non-consecutive slices are forwarded to the underlying
// device.
TEST_F(VPartitionManagerTest, QueueTrimDisjointSlices) {
  auto partition_or = AllocatePartition();
  ASSERT_TRUE(partition_or.is_ok());

  const uint32_t kOperationLength = 20;
  partition_or.value()->SliceSetUnsafe(1, 1);
  partition_or.value()->SliceSetUnsafe(2, 5);

  block_op_t op = {};
  op.trim.command = BLOCK_OP_TRIM;
  op.trim.length = kOperationLength;
  op.trim.offset_dev = kBlocksPerSlice * 2 - kOperationLength / 2;

  partition_or.value()->BlockImplQueue(
      &op, [](void*, zx_status_t status, block_op_t*) {}, nullptr);
  EXPECT_EQ(2, block_device_.num_trim_calls());
  EXPECT_EQ(kOperationLength, block_device_.last_trim_length());
}

TEST_F(VPartitionManagerTest, InspectVmoPopulatedWithInitialState) {
  fpromise::result<inspect::Hierarchy> hierarchy =
      inspect::ReadFromVmo(device_->diagnostics().DuplicateVmo());
  ASSERT_TRUE(hierarchy.is_ok());
  const inspect::Hierarchy* mount_time = hierarchy.value().GetByPath({"fvm", "mount_time"});
  ASSERT_NE(mount_time, nullptr);

  auto* major_version =
      mount_time->node().get_property<inspect::UintPropertyValue>("major_version");
  ASSERT_NE(major_version, nullptr);
  EXPECT_EQ(major_version->value(), kCurrentMajorVersion);

  auto* oldest_minor_version =
      mount_time->node().get_property<inspect::UintPropertyValue>("oldest_minor_version");
  ASSERT_NE(oldest_minor_version, nullptr);
  EXPECT_EQ(oldest_minor_version->value(), kCurrentMinorVersion);
}

TEST_F(VPartitionManagerTest, InspectVmoTracksSliceAllocations) {
  auto partition_or = AllocatePartition("part1", 3u);
  ASSERT_TRUE(partition_or.is_ok());

  {
    fpromise::result<inspect::Hierarchy> hierarchy =
        inspect::ReadFromVmo(device_->diagnostics().DuplicateVmo());
    ASSERT_TRUE(hierarchy.is_ok());
    const inspect::Hierarchy* node = hierarchy.value().GetByPath({"fvm", "partitions", "part1"});
    ASSERT_NE(node, nullptr);
    auto* total_slices_reserved =
        node->node().get_property<inspect::UintPropertyValue>("total_slices_reserved");
    ASSERT_NE(total_slices_reserved, nullptr);
    EXPECT_EQ(total_slices_reserved->value(), 3u);
  }

  ASSERT_EQ(device_->AllocateSlices(partition_or.value().get(), 0x100000, 1), ZX_OK);

  {
    fpromise::result<inspect::Hierarchy> hierarchy =
        inspect::ReadFromVmo(device_->diagnostics().DuplicateVmo());
    ASSERT_TRUE(hierarchy.is_ok());
    const inspect::Hierarchy* node = hierarchy.value().GetByPath({"fvm", "partitions", "part1"});
    ASSERT_NE(node, nullptr);
    auto* total_slices_reserved =
        node->node().get_property<inspect::UintPropertyValue>("total_slices_reserved");
    ASSERT_NE(total_slices_reserved, nullptr);
    EXPECT_EQ(total_slices_reserved->value(), 4u);
  }
}

TEST_F(VPartitionManagerTest, InspectVmoTracksPartitionLimit) {
  constexpr uint64_t kNewSliceLimit = 4u;
  static_assert(kNewSliceLimit > 0, "Slice limit must be greater than zero for test to be valid.");
  static_assert(sizeof(guid_t) == fvm::kGuidSize, "GUID size mismatch!");

  const std::string kPartitionName = "part1";

  auto partition_or = AllocatePartition(kPartitionName, 3u);
  ASSERT_TRUE(partition_or.is_ok());

  guid_t partition_guid;
  ASSERT_EQ(partition_or->BlockPartitionGetGuid(GUIDTYPE_INSTANCE, &partition_guid), ZX_OK);
  const uint8_t* guid_as_bytes = reinterpret_cast<const uint8_t*>(&partition_guid);

  {
    // Initial limit should be set to zero.
    uint64_t slice_limit;
    ASSERT_EQ(device_->GetPartitionLimitInternal(guid_as_bytes, &slice_limit), ZX_OK);
    EXPECT_EQ(slice_limit, 0u);

    fpromise::result<inspect::Hierarchy> hierarchy =
        inspect::ReadFromVmo(device_->diagnostics().DuplicateVmo());
    ASSERT_TRUE(hierarchy.is_ok());
    const inspect::Hierarchy* node =
        hierarchy.value().GetByPath({"fvm", "partitions", kPartitionName});
    ASSERT_NE(node, nullptr);
    auto* max_bytes = node->node().get_property<inspect::UintPropertyValue>("max_bytes");
    ASSERT_NE(max_bytes, nullptr);
    EXPECT_EQ(max_bytes->value(), 0u);
  }

  device_->SetPartitionLimitInternal(guid_as_bytes, kNewSliceLimit);

  {
    // Check that the partition limit was set and is updated in Inspect.
    uint64_t slice_limit;
    ASSERT_EQ(device_->GetPartitionLimitInternal(guid_as_bytes, &slice_limit), ZX_OK);
    EXPECT_EQ(slice_limit, kNewSliceLimit);

    fpromise::result<inspect::Hierarchy> hierarchy =
        inspect::ReadFromVmo(device_->diagnostics().DuplicateVmo());
    ASSERT_TRUE(hierarchy.is_ok());
    const inspect::Hierarchy* node =
        hierarchy.value().GetByPath({"fvm", "partitions", kPartitionName});
    ASSERT_NE(node, nullptr);
    auto* max_bytes = node->node().get_property<inspect::UintPropertyValue>("max_bytes");
    ASSERT_NE(max_bytes, nullptr);
    EXPECT_EQ(max_bytes->value(), kNewSliceLimit * device_->slice_size());
  }
}

// Tests that opening a device at a newer "oldest revision" updates the device's oldest revision to
// the current revision value.
constexpr uint64_t kNextRevision = kCurrentMinorVersion + 1;
using VPartitionManagerTestAtNextRevision = VPartitionManagerTestAtRevision<kNextRevision>;
TEST_F(VPartitionManagerTestAtNextRevision, UpdateOldestRevision) {
  auto first_metadata_or = GetMetadata();
  ASSERT_TRUE(first_metadata_or.is_ok());

  auto first_metadata_type = first_metadata_or.value().active_header();

  // No operations have been performed, the FVM header will be unchanged from initialization and
  // will reference the next revision.
  EXPECT_EQ(first_metadata_or.value().GetHeader().oldest_minor_version, kNextRevision);

  // Trigger a write operation. This allocated a new partition but could be any operation that
  // forces a write to the FVM metadata.
  ASSERT_TRUE(AllocatePartition().is_ok());

  // Read the updated metadata.
  auto second_metadata_or = GetMetadata();
  ASSERT_TRUE(second_metadata_or.is_ok());

  // The active header should have swapped between the primary and secondary copy.
  auto second_metadata_type = second_metadata_or.value().active_header();
  EXPECT_NE(first_metadata_type, second_metadata_type);

  // The newly active header should have the oldest revision downgraded to the current one.
  EXPECT_EQ(second_metadata_or.value().GetHeader().oldest_minor_version, kCurrentMinorVersion);
}

// Tests that opening a device at a older "oldest revision" doesn't change the oldest revision.
constexpr uint64_t kPreviousRevision = kCurrentMinorVersion - 1;
using VPartitionManagerTestAtPreviousRevision = VPartitionManagerTestAtRevision<kPreviousRevision>;
TEST_F(VPartitionManagerTestAtPreviousRevision, DontUpdateOldestRevision) {
  auto first_metadata_or = GetMetadata();
  ASSERT_TRUE(first_metadata_or.is_ok());

  auto first_metadata_type = first_metadata_or.value().active_header();

  // No operations have been performed, the FVM header will be unchanged from initialization and
  // will reference the next revision.
  EXPECT_EQ(first_metadata_or.value().GetHeader().oldest_minor_version, kPreviousRevision);

  // Trigger a write operation. This allocated a new partition but could be any operation that
  // forces a write to the FVM metadata.
  ASSERT_TRUE(AllocatePartition().is_ok());

  // Read the updated metadata.
  auto second_metadata_or = GetMetadata();
  ASSERT_TRUE(second_metadata_or.is_ok());

  // The active header should have swapped between the primary and secondary copy.
  auto second_metadata_type = second_metadata_or.value().active_header();
  EXPECT_NE(first_metadata_type, second_metadata_type);

  // The newly active header should still have the oldest revision unchanged rather than the current
  // one.
  EXPECT_EQ(second_metadata_or.value().GetHeader().oldest_minor_version, kPreviousRevision);
}

}  // namespace fvm
