// Copyright 2021 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/adapter/minfs_partition.h"

#include <lib/fit/result.h>
#include <zircon/hw/gpt.h>

#include <cstdint>
#include <iostream>

#include <safemath/checked_math.h>

#include "src/storage/fvm/format.h"
#include "src/storage/minfs/format.h"
#include "src/storage/minfs/fsck.h"
#include "src/storage/minfs/transaction_limits.h"
#include "src/storage/volume_image/address_descriptor.h"
#include "src/storage/volume_image/options.h"
#include "src/storage/volume_image/utils/block_utils.h"

namespace storage::volume_image {
namespace {

// Expected label for blobfs volume
constexpr std::string_view kMinfsLabel = "data";

// Expected GUID for blobfs instance.
constexpr std::array<uint8_t, kGuidLength> kMinfsTypeGuid = GUID_DATA_VALUE;

// For minfs we need to replace contents from the superblock, to make it look like its fvm based
// minfs.
class PatchedSuperblockReader final : public Reader {
 public:
  explicit PatchedSuperblockReader(std::unique_ptr<Reader> reader, uint64_t superblock_offset)
      : superblock_offset_(superblock_offset), reader_(std::move(reader)) {}

  uint64_t length() const final { return reader_->length(); }

  fit::result<void, std::string> Read(uint64_t offset, fbl::Span<uint8_t> buffer) const final {
    if (auto read_result = reader_->Read(offset, buffer); read_result.is_error()) {
      return read_result.take_error_result();
    }

    if (!(offset + buffer.size() > superblock_offset_) ||
        !(offset <= superblock_offset_ + minfs::kMinfsBlockSize)) {
      return fit::ok();
    }

    uint64_t bytes_before_superblock =
        superblock_offset_ > offset ? superblock_offset_ - offset : 0;
    uint64_t bytes_until_block_end =
        std::min(static_cast<uint64_t>(offset + buffer.size() - bytes_before_superblock),
                 superblock_offset_ + minfs::kMinfsBlockSize) -
        std::max(superblock_offset_, offset);
    memset(buffer.data() + bytes_before_superblock, 0, bytes_until_block_end);
    // now the superblock contents.
    if (offset <= superblock_offset_ + sizeof(minfs::Superblock)) {
      uint64_t bytes_since_superblock_offset =
          offset > superblock_offset_ ? offset - superblock_offset_ : 0;
      uint64_t bytes_remaining_from_superblock =
          sizeof(minfs::Superblock) - bytes_since_superblock_offset;
      uint64_t bytes_remaining_in_buffer =
          buffer.size() - bytes_before_superblock - bytes_since_superblock_offset;
      uint64_t bytes_to_read = std::min(bytes_remaining_in_buffer, bytes_remaining_from_superblock);
      memcpy(buffer.data() + bytes_before_superblock,
             reinterpret_cast<const uint8_t*>(&superblock_) + bytes_since_superblock_offset,
             bytes_to_read);
    }

    return fit::ok();
  };

  minfs::Superblock& superblock() { return superblock_; }

 private:
  minfs::Superblock superblock_;
  uint64_t superblock_offset_;
  std::unique_ptr<Reader> reader_;
};

}  // namespace

fit::result<Partition, std::string> CreateMinfsFvmPartition(
    std::unique_ptr<Reader> source_image, const PartitionOptions& partition_options,
    const FvmOptions& fvm_options) {
  if (fvm_options.slice_size % minfs::kMinfsBlockSize != 0) {
    return fit::error(
        "Fvm slice size must be a multiple of minfs block size. Expected minfs_block_size: " +
        std::to_string(minfs::kMinfsBlockSize) +
        " fvm_slice_size: " + std::to_string(fvm_options.slice_size) + ".");
  }

  // Load minfs superblock to obtain extent sizes and such.
  minfs::Superblock superblock = {};
  if (auto sb_read_result = source_image->Read(
          0,
          fbl::Span<uint8_t>(reinterpret_cast<uint8_t*>(&superblock), sizeof(minfs::Superblock)));
      sb_read_result.is_error()) {
    return sb_read_result.take_error_result();
  }

  // Minor validation that we are actually dealing with a blobfs superblock.
  if (superblock.magic0 != minfs::kMinfsMagic0) {
    return fit::error(
        "Found bad magic0(" + std::to_string(superblock.magic0) +
        ") value in minfs superblock(Expected: " + std::to_string(minfs::kMinfsMagic0) + ").");
  }

  if (superblock.magic1 != minfs::kMinfsMagic1) {
    return fit::error(
        "Found bad magic1(" + std::to_string(superblock.magic1) +
        ") value in minfs superblock(Expected: " + std::to_string(minfs::kMinfsMagic1) + ").");
  }

  // Helper to calculate slice count.
  auto get_slice_count = [&fvm_options](const auto& mapping) {
    auto extent_size = std::max(mapping.count, mapping.size.value_or(0));
    return GetBlockCount(mapping.target, extent_size, fvm_options.slice_size);
  };

  VolumeDescriptor volume;
  volume.block_size = minfs::kMinfsBlockSize;
  volume.size = source_image->length();
  volume.encryption = EncryptionType::kZxcrypt;
  volume.name = kMinfsLabel;
  memcpy(volume.type.data(), kMinfsTypeGuid.data(), volume.type.size());
  memcpy(volume.instance.data(), fvm::kPlaceHolderInstanceGuid.data(), volume.instance.size());

  AddressDescriptor address;

  AddressMap superblock_mapping;
  superblock_mapping.source = 0;
  superblock_mapping.target = 0;
  superblock_mapping.count = sizeof(minfs::Superblock);
  superblock_mapping.options[EnumAsString(AddressMapOption::kFill)] = 0;

  AddressMap inode_bitmap_mapping;
  inode_bitmap_mapping.source = superblock.ibm_block * minfs::kMinfsBlockSize;
  inode_bitmap_mapping.target = minfs::kFVMBlockInodeBmStart * minfs::kMinfsBlockSize;
  inode_bitmap_mapping.count =
      (superblock.abm_block - superblock.ibm_block) * minfs::kMinfsBlockSize;
  inode_bitmap_mapping.size =
      std::max(inode_bitmap_mapping.count, static_cast<uint64_t>(minfs::BlocksRequiredForBits(
                                               partition_options.min_inode_count.value_or(0))) *
                                               minfs::kMinfsBlockSize);
  inode_bitmap_mapping.options[EnumAsString(AddressMapOption::kFill)] = 0;

  AddressMap data_bitmap_mapping;
  data_bitmap_mapping.source = superblock.abm_block * minfs::kMinfsBlockSize;
  data_bitmap_mapping.target = minfs::kFVMBlockDataBmStart * minfs::kMinfsBlockSize;
  data_bitmap_mapping.count =
      (superblock.ino_block - superblock.abm_block) * minfs::kMinfsBlockSize;
  data_bitmap_mapping.size =
      std::max(data_bitmap_mapping.count,
               static_cast<uint64_t>(minfs::BlocksRequiredForBits(GetBlockCount(
                   minfs::kFVMBlockDataBmStart * minfs::kMinfsBlockSize,
                   partition_options.min_data_bytes.value_or(0), minfs::kMinfsBlockSize))));
  data_bitmap_mapping.options[EnumAsString(AddressMapOption::kFill)] = 0;

  AddressMap inode_mapping;
  inode_mapping.source = superblock.ino_block * minfs::kMinfsBlockSize;
  inode_mapping.target = minfs::kFVMBlockInodeStart * minfs::kMinfsBlockSize;
  inode_mapping.count =
      (superblock.integrity_start_block - superblock.ino_block) * minfs::kMinfsBlockSize;
  inode_mapping.size =
      std::max(inode_mapping.count, static_cast<uint64_t>(minfs::BlocksRequiredForInode(
                                        partition_options.min_inode_count.value_or(0))) *
                                        minfs::kMinfsBlockSize);
  inode_mapping.options[EnumAsString(AddressMapOption::kFill)] = 0;

  AddressMap data_mapping;
  data_mapping.source = superblock.dat_block * minfs::kMinfsBlockSize;
  data_mapping.target = minfs::kFVMBlockDataStart * minfs::kMinfsBlockSize;
  data_mapping.count = superblock.block_count * minfs::kMinfsBlockSize;
  data_mapping.size =
      std::max(data_mapping.count,
               GetBlockCount(superblock.dat_block, partition_options.min_data_bytes.value_or(0),
                             minfs::kMinfsBlockSize) *
                   minfs::kMinfsBlockSize);

  AddressMap integrity_mapping;
  integrity_mapping.source = superblock.integrity_start_block * minfs::kMinfsBlockSize;
  integrity_mapping.target = minfs::kFvmSuperblockBackup * minfs::kMinfsBlockSize;
  integrity_mapping.count =
      (superblock.dat_block - superblock.integrity_start_block) * minfs::kMinfsBlockSize;

  auto patched_superblock_reader =
      std::make_unique<PatchedSuperblockReader>(std::move(source_image), 0);

  auto& patched_superblock = patched_superblock_reader->superblock();
  patched_superblock = superblock;

  patched_superblock.slice_size = fvm_options.slice_size;
  patched_superblock.flags |= minfs::kMinfsFlagFVM;

  patched_superblock.ibm_slices = get_slice_count(inode_bitmap_mapping);
  patched_superblock.abm_slices = get_slice_count(data_bitmap_mapping);
  patched_superblock.ino_slices = get_slice_count(inode_mapping);
  patched_superblock.dat_slices = get_slice_count(data_mapping);

  patched_superblock.inode_count = safemath::checked_cast<uint32_t>(
      get_slice_count(inode_mapping) * fvm_options.slice_size / minfs::kMinfsInodeSize);
  patched_superblock.block_count = safemath::checked_cast<uint32_t>(
      get_slice_count(data_mapping) * fvm_options.slice_size / minfs::kMinfsBlockSize);

  patched_superblock.ibm_block = minfs::kFVMBlockInodeBmStart;
  patched_superblock.abm_block = minfs::kFVMBlockDataBmStart;
  patched_superblock.ino_block = minfs::kFVMBlockInodeStart;
  patched_superblock.integrity_start_block = minfs::kFvmSuperblockBackup;
  patched_superblock.dat_block = minfs::kFVMBlockDataStart;

  // Calculate recommended journal slices based on the patched superblock.
  minfs::TransactionLimits limits(patched_superblock);

  integrity_mapping.size = std::max(
      integrity_mapping.count,
      static_cast<uint64_t>(limits.GetRecommendedIntegrityBlocks()) * minfs::kMinfsBlockSize);
  patched_superblock.integrity_slices = get_slice_count(integrity_mapping);

  minfs::UpdateChecksum(&patched_superblock);

  auto patched_superblock_and_backup_superblock_reader = std::make_unique<PatchedSuperblockReader>(
      std::move(patched_superblock_reader),
      superblock.integrity_start_block * minfs::kMinfsBlockSize);
  patched_superblock_and_backup_superblock_reader->superblock() = patched_superblock;

  address.mappings.push_back(superblock_mapping);
  address.mappings.push_back(inode_bitmap_mapping);
  address.mappings.push_back(data_bitmap_mapping);
  address.mappings.push_back(inode_mapping);
  address.mappings.push_back(integrity_mapping);
  address.mappings.push_back(data_mapping);

  uint64_t accumulated_slices = 0;
  for (const auto& mapping : address.mappings) {
    accumulated_slices += get_slice_count(mapping);
  }
  uint64_t accumulated_bytes = accumulated_slices * fvm_options.slice_size;

  if (partition_options.max_bytes.has_value() &&
      accumulated_bytes > partition_options.max_bytes.value()) {
    return fit::error("Minfs FVM Partition allocated " + std::to_string(accumulated_slices) + "(" +
                      std::to_string(accumulated_bytes) +
                      " bytes) exceeding provided upperbound |max_bytes|(" +
                      std::to_string(partition_options.max_bytes.value()) + ").");
  }

  return fit::ok(
      Partition(volume, address, std::move(patched_superblock_and_backup_superblock_reader)));
}

}  // namespace storage::volume_image
