// 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/host/internal_snapshot_meta_format.h"

#include <inttypes.h>
#include <zircon/errors.h>

#include <limits>
#include <utility>

#include <safemath/checked_math.h>

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

namespace {

template <class T>
uint32_t ToU32(T in) {
  if (in > std::numeric_limits<uint32_t>::max()) {
    fprintf(stderr, "%s:%d out of range %" PRIuMAX "\n", __FILE__, __LINE__,
            safemath::checked_cast<uintmax_t>(in));
    exit(-1);
  }
  return safemath::checked_cast<uint32_t>(in);
}

}  // namespace

InternalSnapshotMetaFormat::InternalSnapshotMetaFormat(
    size_t reserved_slices, size_t slice_size,
    const std::vector<fvm::PartitionSnapshotState>& partitions,
    const std::vector<fvm::SnapshotExtentType>& extents)
    : Format(), reserved_slices_(reserved_slices), slice_size_(slice_size) {
  meta_ = fvm::SnapshotMetadata::Synthesize(partitions.data(), partitions.size(), extents.data(),
                                            extents.size())
              .value();
  zero_buf_ = std::unique_ptr<uint8_t[]>(new uint8_t[meta_.Get()->size()]);
}

InternalSnapshotMetaFormat::~InternalSnapshotMetaFormat() = default;

zx::status<ExtentInfo> InternalSnapshotMetaFormat::GetExtent(unsigned index) const {
  if (index == 0) {
    return zx::ok(ExtentInfo{
        .vslice_start = 0,
        .vslice_count = ToU32(reserved_slices_),
        .block_offset = 0,
        .block_count = 1,
        .zero_fill = false,
    });
  }
  return zx::error(ZX_ERR_OUT_OF_RANGE);
}

zx_status_t InternalSnapshotMetaFormat::GetSliceCount(uint32_t* slices_out) const {
  *slices_out = reserved_slices_;
  return ZX_OK;
}

zx_status_t InternalSnapshotMetaFormat::FillBlock(size_t block_offset) {
  if (block_offset == 0) {
    // We'll read directly from meta_ later.
    reading_from_meta_ = true;
    return ZX_OK;
  }
  reading_from_meta_ = false;
  return ZX_OK;
}

zx_status_t InternalSnapshotMetaFormat::EmptyBlock() {
  reading_from_meta_ = false;
  return ZX_OK;
}

void* InternalSnapshotMetaFormat::Data() {
  return reading_from_meta_ ? meta_.Get()->data() : zero_buf_.get();
}

const char* InternalSnapshotMetaFormat::Name() const { return "internal"; }

uint32_t InternalSnapshotMetaFormat::BlockSize() const { return meta_.Get()->size(); }

uint32_t InternalSnapshotMetaFormat::BlocksPerSlice() const {
  return ToU32(slice_size_ / BlockSize());
}
