// 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/fvm/metadata.h"

#include <lib/zx/status.h>
#include <zircon/types.h>

#include <memory>
#include <optional>
#include <vector>

#include <fbl/span.h>
#include <safemath/checked_math.h>

#include "src/storage/fvm/format.h"
#include "src/storage/fvm/fvm.h"

namespace fvm {

namespace {

// Returns a byte view of a fixed size struct.
template <typename T>
fbl::Span<const uint8_t> FixedSizeStructToSpan(const T& typed_content) {
  return fbl::Span<const uint8_t>(reinterpret_cast<const uint8_t*>(&typed_content), sizeof(T));
}

// Returns a byte view of an array of structs.
template <typename T>
fbl::Span<const uint8_t> ContainerToSpan(const T& container) {
  if (container.empty()) {
    return fbl::Span<const uint8_t>();
  }
  return fbl::Span<const uint8_t>(reinterpret_cast<const uint8_t*>(container.data()),
                                  container.size() * sizeof(*container.data()));
}

}  // namespace

size_t Metadata::BytesNeeded(const fvm::Header& header) {
  return header.GetMetadataAllocatedBytes();
}

Metadata::Metadata(std::unique_ptr<MetadataBuffer> data, SuperblockType active_header)
    : data_(std::move(data)), active_header_(active_header) {}

Metadata::Metadata(Metadata&& o) noexcept { MoveFrom(std::move(o)); }

Metadata& Metadata::operator=(Metadata&& o) noexcept {
  MoveFrom(std::move(o));
  return *this;
}

void Metadata::MoveFrom(Metadata&& o) {
  data_ = std::move(o.data_);
  active_header_ = o.active_header_;
}

bool Metadata::CheckValidity(uint64_t disk_size, uint64_t disk_block_size) const {
  std::string header_err;
  bool valid = GetHeader().IsValid(disk_size, disk_block_size, header_err);
  if (!valid) {
    fprintf(stderr, "Invalid header: %s\n", header_err.c_str());
  }
  return valid;
}

void Metadata::UpdateHash() {
  ::fvm::UpdateHash(static_cast<uint8_t*>(data_->data()), GetHeader().GetMetadataUsedBytes());
}

size_t Metadata::GetInactiveHeaderOffset() const {
  return GetHeader().GetSuperblockOffset(inactive_header());
}

void Metadata::SwitchActiveHeaders() { active_header_ = OppositeHeader(active_header_); }

Header& Metadata::GetHeader() const {
  return *reinterpret_cast<Header*>(static_cast<uint8_t*>(data_->data()));
}

VPartitionEntry& Metadata::GetPartitionEntry(unsigned idx) const {
  const Header& header = GetHeader();
  size_t offset = MetadataOffset(SuperblockType::kPrimary) + header.GetPartitionEntryOffset(idx);
  ZX_ASSERT(offset + sizeof(VPartitionEntry) <= data_->size());
  if (idx > header.GetPartitionTableEntryCount()) {
    fprintf(stderr,
            "fatal: Accessing out-of-bounds partition (idx %u, table has %lu usable entries)\n",
            idx, header.GetPartitionTableEntryCount());
    ZX_ASSERT(idx <= header.GetPartitionTableEntryCount());
  }
  return *reinterpret_cast<VPartitionEntry*>(reinterpret_cast<uint8_t*>(data_->data()) + offset);
}

SliceEntry& Metadata::GetSliceEntry(unsigned idx) const {
  const Header& header = GetHeader();
  size_t offset = MetadataOffset(SuperblockType::kPrimary) + header.GetSliceEntryOffset(idx);
  ZX_ASSERT(offset + sizeof(SliceEntry) <= data_->size());
  if (idx > header.GetAllocationTableUsedEntryCount()) {
    fprintf(stderr, "fatal: Accessing out-of-bounds slice (idx %u, table has %lu usable entries)\n",
            idx, header.GetAllocationTableUsedEntryCount());
    ZX_ASSERT(idx <= header.GetAllocationTableUsedEntryCount());
  }
  return *reinterpret_cast<SliceEntry*>(reinterpret_cast<uint8_t*>(data_->data()) + offset);
}

size_t Metadata::MetadataOffset(SuperblockType type) const {
  return GetHeader().GetSuperblockOffset(type);
}

const MetadataBuffer* Metadata::Get() const { return data_.get(); }

zx::status<Metadata> Metadata::CopyWithNewDimensions(const Header& dimensions) const {
  if (BytesNeeded(dimensions) < data_->size()) {
    return zx::error(ZX_ERR_BUFFER_TOO_SMALL);
  }
  const Header& header = GetHeader();
  if (dimensions.fvm_partition_size < header.fvm_partition_size ||
      dimensions.GetPartitionTableEntryCount() < header.GetPartitionTableEntryCount() ||
      dimensions.GetAllocationTableUsedEntryCount() < header.GetAllocationTableUsedEntryCount() ||
      dimensions.GetAllocationTableAllocatedEntryCount() <
          header.GetAllocationTableAllocatedEntryCount()) {
    return zx::error(ZX_ERR_BUFFER_TOO_SMALL);
  }

  Header new_header = header;
  new_header.fvm_partition_size = dimensions.fvm_partition_size;
  new_header.pslice_count = dimensions.pslice_count;
  new_header.vpartition_table_size = dimensions.vpartition_table_size;
  new_header.allocation_table_size = dimensions.allocation_table_size;

  // TODO(fxbug.dev/59980) The first entries in the partition/slice tables must be unused.
  // |Synthesize()| expects an array that does *not* include the empty zero entries.
  // Remove this after we support zero-indexing.
  const VPartitionEntry* partitions = nullptr;
  size_t num_partitions = header.GetPartitionTableEntryCount();
  if (num_partitions <= 1) {
    // Both 0 and 1 partitions count as having no partitions to copy.
    num_partitions = 0;
  } else {
    partitions = &GetPartitionEntry(1u);
  }
  const SliceEntry* slices = nullptr;
  size_t num_slices = header.GetAllocationTableUsedEntryCount();
  if (num_slices <= 1) {
    // Both 0 and 1 slices count as having no slices to copy.
    num_slices = 0;
  } else {
    slices = &GetSliceEntry(1u);
  }

  return Synthesize(new_header, partitions, num_partitions, slices, num_slices);
}

zx::status<Metadata> Metadata::Create(std::unique_ptr<MetadataBuffer> data_a,
                                      std::unique_ptr<MetadataBuffer> data_b) {
  return Create(std::numeric_limits<uint64_t>::max(), kBlockSize, std::move(data_a),
                std::move(data_b));
}

zx::status<Metadata> Metadata::Create(size_t disk_size, size_t disk_block_size,
                                      std::unique_ptr<MetadataBuffer> data_a,
                                      std::unique_ptr<MetadataBuffer> data_b) {
  if (data_a->size() < sizeof(Header)) {
    return zx::error(ZX_ERR_BUFFER_TOO_SMALL);
  }
  if (data_b->size() < sizeof(Header)) {
    return zx::error(ZX_ERR_BUFFER_TOO_SMALL);
  }

  // For now just assume header is valid. It may contain nonsense, but PickValidHeader will check
  // this, and we can at least check that the offset is reasonable so we don't overflow now.
  const Header* header = reinterpret_cast<const Header*>(data_a->data());
  size_t meta_size = header->GetMetadataAllocatedBytes();
  if (meta_size > data_a->size() || meta_size > data_b->size()) {
    fprintf(stderr, "fvm: Metadata (%lu bytes) too large for buffers (%lu and %lu bytes)\n",
            meta_size, data_a->size(), data_b->size());
    return zx::error(ZX_ERR_IO_DATA_INTEGRITY);
  }
  std::optional<SuperblockType> active_header =
      PickValidHeader(disk_size, disk_block_size, data_a->data(), data_b->data(), meta_size);
  if (!active_header) {
    return zx::error(ZX_ERR_IO_DATA_INTEGRITY);
  }

  std::unique_ptr<MetadataBuffer> data;
  switch (active_header.value()) {
    case SuperblockType::kPrimary:
      data = std::move(data_a);
      break;
    case SuperblockType::kSecondary:
      data = std::move(data_b);
      break;
  }
  return zx::ok(Metadata(std::move(data), active_header.value()));
}

zx::status<Metadata> Metadata::Synthesize(const fvm::Header& header,
                                          const VPartitionEntry* partitions, size_t num_partitions,
                                          const SliceEntry* slices, size_t num_slices) {
  if (num_partitions > header.GetPartitionTableEntryCount() ||
      num_slices > header.GetAllocationTableUsedEntryCount() || header.slice_size == 0) {
    return zx::error(ZX_ERR_INVALID_ARGS);
  }

  size_t buffer_size = BytesNeeded(header);
  std::unique_ptr<uint8_t[]> buf(new uint8_t[buffer_size]);

  // TODO(fxbug.dev/59980) The first entries in the partition/slice tables must be unused.
  // Remove this after we support zero-indexing.
  std::vector<VPartitionEntry> actual_partitions(0);
  if (num_partitions > 0) {
    ZX_ASSERT(partitions != nullptr);
    actual_partitions = std::vector<VPartitionEntry>(num_partitions + 1);
    actual_partitions[0].Release();
    for (size_t i = 0; i < num_partitions; ++i) {
      actual_partitions[i + 1] = partitions[i];
    }
  }
  std::vector<SliceEntry> actual_slices(0);
  if (num_slices > 0) {
    ZX_ASSERT(slices != nullptr);
    actual_slices = std::vector<SliceEntry>(num_slices + 1);
    actual_slices[0].Release();
    for (size_t i = 0; i < num_slices; ++i) {
      actual_slices[i + 1] = slices[i];
    }
  }

  const fbl::Span<const uint8_t> header_span = FixedSizeStructToSpan(header);
  const fbl::Span<const uint8_t> partitions_span = ContainerToSpan(actual_partitions);
  const fbl::Span<const uint8_t> slices_span = ContainerToSpan(actual_slices);

  auto write_metadata = [&](size_t offset, size_t sz, const fbl::Span<const uint8_t>& span) {
    ZX_ASSERT(offset + sz <= buffer_size);
    ZX_ASSERT(sz >= span.size());
    if (!span.empty()) {
      memcpy(buf.get() + offset, span.data(), span.size());
    }
    bzero(buf.get() + offset + span.size(), sz - span.size());
  };

  write_metadata(0, fvm::kBlockSize, header_span);
  write_metadata(header.GetPartitionTableOffset(), header.GetPartitionTableByteSize(),
                 partitions_span);
  write_metadata(header.GetAllocationTableOffset(), header.GetAllocationTableAllocatedByteSize(),
                 slices_span);
  // TODO(fxbug.dev/59567): Synthesize snapshot metadata.

  ::fvm::UpdateHash(buf.get(), header.GetMetadataUsedBytes());

  Metadata metadata(std::make_unique<HeapMetadataBuffer>(std::move(buf), buffer_size),
                    SuperblockType::kPrimary);
  if (!metadata.CheckValidity()) {
    return zx::error(ZX_ERR_INVALID_ARGS);
  }
  return zx::ok(std::move(metadata));
}

}  // namespace fvm
