// Copyright 2018 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 "utils.h"

#include <memory>

#include <fbl/auto_call.h>
#include <gtest/gtest.h>
#include <safemath/checked_math.h>
#include <storage/buffer/owned_vmoid.h>

using id_allocator::IdAllocator;

namespace blobfs {

namespace {

storage::OwnedVmoid AttachVmo(BlockDevice* device, zx::vmo* vmo) {
  storage::Vmoid vmoid;
  EXPECT_EQ(device->BlockAttachVmo(*vmo, &vmoid), ZX_OK);
  return storage::OwnedVmoid(std::move(vmoid), device);
}

// Verify that the |size| and |offset| are |device| block size aligned.
// Returns block_size in |out_block_size|.
void VerifySizeBlockAligned(BlockDevice* device, size_t size, uint64_t offset,
                            uint32_t* out_block_size) {
  fuchsia_hardware_block_BlockInfo info = {};
  ASSERT_EQ(device->BlockGetInfo(&info), ZX_OK);
  ASSERT_EQ(size % info.block_size, 0ul);
  ASSERT_EQ(offset % info.block_size, 0ul);
  *out_block_size = info.block_size;
}

}  // namespace

zx_status_t MockTransactionManager::Transaction(block_fifo_request_t* requests, size_t count) {
  fbl::AutoLock lock(&lock_);

  if (transaction_callback_) {
    for (size_t i = 0; i < count; i++) {
      if (attached_vmos_.size() < requests[i].vmoid) {
        return ZX_ERR_INVALID_ARGS;
      }

      std::optional<zx::vmo>* optional_vmo = &attached_vmos_[requests[i].vmoid - 1];

      if (!optional_vmo->has_value()) {
        return ZX_ERR_BAD_STATE;
      }

      const zx::vmo& dest_vmo = optional_vmo->value();

      if (dest_vmo.get() == ZX_HANDLE_INVALID) {
        return ZX_ERR_INVALID_ARGS;
      }

      zx_status_t status = transaction_callback_(requests[i], dest_vmo);
      if (status != ZX_OK) {
        return status;
      }
    }
  }

  return ZX_OK;
}

zx_status_t MockTransactionManager::BlockAttachVmo(const zx::vmo& vmo, storage::Vmoid* out) {
  fbl::AutoLock lock(&lock_);
  zx::vmo duplicate_vmo;
  zx_status_t status = vmo.duplicate(ZX_RIGHT_SAME_RIGHTS, &duplicate_vmo);
  if (status != ZX_OK) {
    return status;
  }
  attached_vmos_.push_back(std::move(duplicate_vmo));
  *out = storage::Vmoid(static_cast<uint16_t>(attached_vmos_.size()));
  if (out->get() == 0) {
    return ZX_ERR_OUT_OF_RANGE;
  }
  return ZX_OK;
}

zx_status_t MockTransactionManager::BlockDetachVmo(storage::Vmoid vmoid) {
  fbl::AutoLock lock(&lock_);
  vmoid_t id = vmoid.TakeId();
  if (attached_vmos_.size() < id) {
    return ZX_ERR_INVALID_ARGS;
  }

  attached_vmos_[id - 1].reset();
  return ZX_OK;
}

// Create a block and node map of the requested size, update the superblock of
// the |space_manager|, and create an allocator from this provided info.
void InitializeAllocator(size_t blocks, size_t nodes, MockSpaceManager* space_manager,
                         std::unique_ptr<Allocator>* out) {
  RawBitmap block_map;
  ASSERT_EQ(block_map.Reset(blocks), ZX_OK);
  fzl::ResizeableVmoMapper node_map;
  ASSERT_EQ(node_map.CreateAndMap(nodes * kBlobfsBlockSize, "node map"), ZX_OK);

  space_manager->MutableInfo().inode_count = nodes;
  space_manager->MutableInfo().data_block_count = blocks;
  std::unique_ptr<IdAllocator> nodes_bitmap = {};
  ASSERT_EQ(IdAllocator::Create(nodes, &nodes_bitmap), ZX_OK);
  *out = std::make_unique<Allocator>(space_manager, std::move(block_map), std::move(node_map),
                                     std::move(nodes_bitmap));
  (*out)->SetLogging(false);
}

// Force the allocator to become maximally fragmented by allocating
// every-other block within up to |blocks|.
void ForceFragmentation(Allocator* allocator, size_t blocks) {
  fbl::Vector<ReservedExtent> extents[blocks];
  for (size_t i = 0; i < blocks; i++) {
    ASSERT_EQ(allocator->ReserveBlocks(1, &extents[i]), ZX_OK);
    ASSERT_EQ(1ul, extents[i].size());
  }

  for (size_t i = 0; i < blocks; i += 2) {
    allocator->MarkBlocksAllocated(extents[i][0]);
  }
}

// Save the extents within |in| in a non-reserved vector |out|.
void CopyExtents(const fbl::Vector<ReservedExtent>& in, fbl::Vector<Extent>* out) {
  out->reserve(in.size());
  for (size_t i = 0; i < in.size(); i++) {
    out->push_back(in[i].extent());
  }
}

// Save the nodes within |in| in a non-reserved vector |out|.
void CopyNodes(const fbl::Vector<ReservedNode>& in, fbl::Vector<uint32_t>* out) {
  out->reserve(in.size());
  for (size_t i = 0; i < in.size(); i++) {
    out->push_back(in[i].index());
  }
}

void DeviceBlockRead(BlockDevice* device, void* buf, size_t size, uint64_t dev_offset) {
  uint32_t block_size;
  VerifySizeBlockAligned(device, size, dev_offset, &block_size);

  zx::vmo vmo;
  ASSERT_EQ(zx::vmo::create(size, 0, &vmo), ZX_OK);

  storage::OwnedVmoid vmoid = AttachVmo(device, &vmo);

  block_fifo_request_t request;
  request.opcode = BLOCKIO_READ;
  request.vmoid = vmoid.get();
  request.length = safemath::checked_cast<uint32_t>(size / block_size);
  request.vmo_offset = 0;
  request.dev_offset = safemath::checked_cast<uint32_t>(dev_offset / block_size);
  ASSERT_EQ(device->FifoTransaction(&request, 1), ZX_OK);
  ASSERT_EQ(vmo.read(buf, 0, size), ZX_OK);
}

void DeviceBlockWrite(BlockDevice* device, const void* buf, size_t size, uint64_t dev_offset) {
  uint32_t block_size;
  VerifySizeBlockAligned(device, size, dev_offset, &block_size);

  zx::vmo vmo;
  ASSERT_EQ(zx::vmo::create(size, 0, &vmo), ZX_OK);
  ASSERT_EQ(vmo.write(buf, 0, size), ZX_OK);

  storage::OwnedVmoid vmoid = AttachVmo(device, &vmo);

  block_fifo_request_t request;
  request.opcode = BLOCKIO_WRITE;
  request.vmoid = vmoid.get();
  request.length = safemath::checked_cast<uint32_t>(size / block_size);
  request.vmo_offset = 0;
  request.dev_offset = safemath::checked_cast<uint32_t>(dev_offset / block_size);
  ASSERT_EQ(device->FifoTransaction(&request, 1), ZX_OK);
}

}  // namespace blobfs
