// Copyright 2020 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/volume_image/fvm/fvm_sparse_image_reader.h"

#include <fidl/fuchsia.device/cpp/wire.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/device-watcher/cpp/device-watcher.h>
#include <lib/fdio/fdio.h>
#include <lib/fzl/resizeable-vmo-mapper.h>
#include <zircon/hw/gpt.h>

#include <fbl/unique_fd.h>
#include <gtest/gtest.h>

#include "src/storage/fvm/format.h"
#include "src/storage/fvm/fvm_sparse.h"
#include "src/storage/lib/block_client/cpp/remote_block_device.h"
#include "src/storage/lib/fs_management/cpp/admin.h"
#include "src/storage/lib/fs_management/cpp/fvm.h"
#include "src/storage/testing/fvm.h"
#include "src/storage/testing/ram_disk.h"
#include "src/storage/volume_image/ftl/ftl_image.h"
#include "src/storage/volume_image/ftl/options.h"
#include "src/storage/volume_image/utils/fd_reader.h"
#include "src/storage/volume_image/utils/writer.h"

namespace storage::volume_image {
namespace {

constexpr std::string_view sparse_image_path = "/pkg/data/test_fvm.sparse.blk";

zx::result<std::string> AttachFvm(const std::string& device_path) {
  std::string controller_path = device_path + "/device_controller";
  zx::result controller = component::Connect<fuchsia_device::Controller>(controller_path);
  if (controller.is_error()) {
    return controller.take_error();
  }
  if (auto status = storage::BindFvm(controller.value()); status.is_error())
    return status.take_error();
  std::string fvm_disk_path = device_path + "/fvm";
  if (zx::result channel = device_watcher::RecursiveWaitForFile(fvm_disk_path.c_str(), zx::sec(3));
      channel.is_error()) {
    return channel.take_error();
  }
  return zx::ok(fvm_disk_path);
}

// Create a ram-disk and copy the output directly into the ram-disk, and then see if FVM can read
// it and minfs Fsck passes.
TEST(FvmSparseImageReaderTest, PartitionsInImagePassFsck) {
  auto base_reader_or = FdReader::Create(sparse_image_path);
  ASSERT_TRUE(base_reader_or.is_ok()) << base_reader_or.error();
  auto sparse_image_or = OpenSparseImage(base_reader_or.value(), std::nullopt);
  ASSERT_TRUE(sparse_image_or.is_ok()) << sparse_image_or.error();

  // Create a ram-disk.
  constexpr int kDeviceBlockSize = 8192;
  const uint64_t disk_size = sparse_image_or.value().volume().size;
  auto ram_disk_or = storage::RamDisk::Create(kDeviceBlockSize, disk_size / kDeviceBlockSize);
  ASSERT_TRUE(ram_disk_or.is_ok()) << ram_disk_or.status_string();

  // Open the ram disk
  zx::result channel =
      component::Connect<fuchsia_hardware_block_volume::Volume>(ram_disk_or.value().path());
  ASSERT_TRUE(channel.is_ok()) << channel.status_string();

  zx::result device = block_client::RemoteBlockDevice::Create(std::move(channel.value()));
  ASSERT_TRUE(device.is_ok()) << device.status_string();
  std::unique_ptr<block_client::RemoteBlockDevice> client = std::move(device.value());

  constexpr uint64_t kInitialVmoSize = 1048576;
  auto vmo = fzl::ResizeableVmoMapper::Create(kInitialVmoSize, "test");
  ASSERT_TRUE(vmo);

  storage::Vmoid vmoid;
  ASSERT_EQ(client->BlockAttachVmo(vmo->vmo(), &vmoid), ZX_OK);
  // This is a test, so we don't need to worry about cleaning it up.
  vmoid_t vmo_id = vmoid.TakeId();

  memset(vmo->start(), 0xaf, kInitialVmoSize);

  // Initialize the entire ramdisk with a filler (that isn't zero).
  for (uint64_t offset = 0; offset < disk_size; offset += kInitialVmoSize) {
    block_fifo_request_t request = {
        .command = {.opcode = BLOCK_OPCODE_WRITE, .flags = 0},
        .vmoid = vmo_id,
        .length =
            static_cast<uint32_t>(std::min(disk_size - offset, kInitialVmoSize) / kDeviceBlockSize),
        .dev_offset = offset / kDeviceBlockSize};
    ASSERT_EQ(client->FifoTransaction(&request, 1), ZX_OK);
  }

  for (const AddressMap& map : sparse_image_or.value().address().mappings) {
    ASSERT_EQ(map.count % kDeviceBlockSize, 0u);
    ASSERT_EQ(map.target % kDeviceBlockSize, 0u);
    ASSERT_LT(map.target, disk_size);
    ASSERT_LE(map.target + map.count, disk_size);
    EXPECT_TRUE(map.options.empty());

    if (vmo->size() < map.count) {
      ASSERT_EQ(vmo->Grow(map.count), ZX_OK);
    }
    auto result = sparse_image_or.value().reader()->Read(
        map.source, cpp20::span<uint8_t>(reinterpret_cast<uint8_t*>(vmo->start()), map.count));
    ASSERT_TRUE(result.is_ok()) << result.error();

    // Write the mapping to the ram disk.
    block_fifo_request_t request = {
        .command = {.opcode = BLOCK_OPCODE_WRITE, .flags = 0},
        .vmoid = vmo_id,
        .length = static_cast<uint32_t>(map.count / kDeviceBlockSize),
        .dev_offset = map.target / kDeviceBlockSize,
    };

    ASSERT_EQ(client->FifoTransaction(&request, 1), ZX_OK)
        << "length=" << request.length << ", dev_offset=" << request.dev_offset;
  }

  client.reset();

  // Now try and attach FVM.
  auto result = AttachFvm(ram_disk_or.value().path());
  ASSERT_TRUE(result.is_ok()) << result.status_string();

  fs_management::PartitionMatcher matcher{
      .type_guids = {GUID_DATA_VALUE},
  };

  ASSERT_EQ(fs_management::OpenPartition(matcher, true).status_value(), ZX_OK);

  // Attempt to fsck minfs.
  {
    zx::result partition = fs_management::OpenPartition(matcher, true);
    ASSERT_EQ(ZX_OK, partition.status_value());
    fidl::WireResult path = fidl::WireCall(partition.value())->GetTopologicalPath();
    ASSERT_EQ(ZX_OK, path.status());

    // And finally run fsck on the volume.
    fs_management::FsckOptions options{
        .verbose = false,
        .never_modify = true,
        .always_modify = false,
        .force = true,
    };
    auto component = fs_management::FsComponent::FromDiskFormat(fs_management::kDiskFormatMinfs);
    EXPECT_EQ(fs_management::Fsck(path->value()->path.get(), component, options), ZX_OK);
  }

  // Attempt to fsck blobfs.
  {
    fs_management::PartitionMatcher matcher{
        .type_guids = {GUID_BLOB_VALUE},
    };
    zx::result partition = fs_management::OpenPartition(matcher, true);
    ASSERT_EQ(ZX_OK, partition.status_value());
    fidl::WireResult path = fidl::WireCall(partition.value())->GetTopologicalPath();
    ASSERT_EQ(ZX_OK, path.status());

    ASSERT_EQ(fs_management::OpenPartition(matcher, true).status_value(), ZX_OK);

    // And finally run fsck on the volume.
    fs_management::FsckOptions options{
        .verbose = false,
        .never_modify = true,
        .always_modify = false,
        .force = true,
    };
    auto component = fs_management::FsComponent::FromDiskFormat(fs_management::kDiskFormatBlobfs);
    EXPECT_EQ(fs_management::Fsck(path->value()->path.get(), component, options), ZX_OK);
  }
}

class NullWriter : public Writer {
 public:
  fpromise::result<void, std::string> Write(uint64_t offset,
                                            cpp20::span<const uint8_t> buffer) override {
    return fpromise::ok();
  }
};

TEST(FvmSparseImageReaderTest, ImageWithMaxSizeAllocatesEnoughMetadata) {
  auto base_reader_or = FdReader::Create(sparse_image_path);
  ASSERT_TRUE(base_reader_or.is_ok()) << base_reader_or.error();

  fvm::SparseImage image = {};
  auto image_stream = cpp20::span<uint8_t>(reinterpret_cast<uint8_t*>(&image), sizeof(image));
  auto read_result = base_reader_or.value().Read(0, image_stream);
  ASSERT_TRUE(read_result.is_ok()) << read_result.error();
  ASSERT_EQ(image.magic, fvm::kSparseFormatMagic);

  auto sparse_image_or = OpenSparseImage(base_reader_or.value(), 300 << 20);
  ASSERT_TRUE(sparse_image_or.is_ok()) << sparse_image_or.error();
  auto sparse_image = sparse_image_or.take_value();

  auto expected_header =
      fvm::Header::FromDiskSize(fvm::kMaxUsablePartitions, 300 << 20, image.slice_size);

  fvm::Header header = {};
  auto header_stream = cpp20::span<uint8_t>(reinterpret_cast<uint8_t*>(&header), sizeof(header));
  read_result = sparse_image.reader()->Read(
      sparse_image.reader()->length() - expected_header.GetMetadataAllocatedBytes(), header_stream);
  ASSERT_TRUE(read_result.is_ok()) << read_result.error();
  ASSERT_EQ(header.magic, fvm::kMagic);

  EXPECT_EQ(expected_header.GetMetadataAllocatedBytes(), header.GetMetadataAllocatedBytes());
}

// This doesn't test that the resulting image is valid, but it least tests that FtlImageWrite can
// consume the sparse image without complaining.
TEST(FvmSparseImageReaderTest, WriteFtlImageSucceeds) {
  auto base_reader_or = FdReader::Create(sparse_image_path);
  ASSERT_TRUE(base_reader_or.is_ok()) << base_reader_or.error();
  auto sparse_image_or = OpenSparseImage(base_reader_or.value(), std::nullopt);
  ASSERT_TRUE(sparse_image_or.is_ok()) << sparse_image_or.error();

  constexpr int kFtlPageSize = 8192;
  NullWriter writer;
  auto result = FtlImageWrite(
      RawNandOptions{
          .page_size = kFtlPageSize,
          .page_count = static_cast<uint32_t>(sparse_image_or.value().volume().size / kFtlPageSize),
          .pages_per_block = 32,
          .oob_bytes_size = 16,
      },
      sparse_image_or.value(), &writer);
  EXPECT_TRUE(result.is_ok()) << result.error();
}

}  // namespace
}  // namespace storage::volume_image
