// 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 <lib/fzl/resizeable-vmo-mapper.h>

#include <iterator>
#include <memory>
#include <utility>
#include <vector>

#include <fbl/algorithm.h>
#include <zxtest/zxtest.h>

// Note: these tests focus on the added functionality of the resizable VMO
// mapper.  The core functionality is assumed to have already been tested by the
// vmo/vmar tests.
namespace {

constexpr char vmo_name[ZX_MAX_NAME_LEN] = "my-vmo";
constexpr size_t kNonRootVmarSize = (512 << 20);
constexpr zx_vm_option_t kNonRootVmarOpts =
    ZX_VM_CAN_MAP_SPECIFIC | ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE;

void ValidateCreateHelper(const fzl::ResizeableVmoMapper& mapper, uint64_t size) {
  ASSERT_TRUE(mapper.vmo().is_valid());
  ASSERT_EQ(mapper.size(), size);
  ASSERT_NOT_NULL(mapper.start());

  auto data = static_cast<const uint8_t*>(mapper.start());
  for (size_t i = 0; i < size; ++i) {
    ASSERT_EQ(data[i], 0);
  }

  char name[ZX_MAX_NAME_LEN] = {};
  zx_status_t status = mapper.vmo().get_property(ZX_PROP_NAME, name, std::size(name));
  ASSERT_EQ(status, ZX_OK);
  for (size_t i = 0; i < std::size(name); ++i) {
    ASSERT_EQ(name[i], vmo_name[i]);
  }
}

template <bool NON_ROOT_VMAR>
void UncheckedCreateHelper(std::unique_ptr<fzl::ResizeableVmoMapper>* out_mapper, uint64_t size,
                           const char* name,
                           zx_vm_option_t map_options = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
                           uint32_t cache_policy = 0) {
  fbl::RefPtr<fzl::VmarManager> manager;
  if (NON_ROOT_VMAR) {
    manager = fzl::VmarManager::Create(kNonRootVmarSize, nullptr, kNonRootVmarOpts);
    ASSERT_NOT_NULL(manager);
  }

  ASSERT_NOT_NULL(out_mapper);
  *out_mapper =
      fzl::ResizeableVmoMapper::Create(size, name, map_options, std::move(manager), cache_policy);
}

template <bool NON_ROOT_VMAR>
void CreateHelper(std::unique_ptr<fzl::ResizeableVmoMapper>* out_mapper, uint64_t size,
                  const char* name, zx_vm_option_t map_options = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
                  uint32_t cache_policy = 0) {
  ASSERT_NO_FATAL_FAILURE(
      UncheckedCreateHelper<NON_ROOT_VMAR>(out_mapper, size, name, map_options, cache_policy));
  ASSERT_NOT_NULL(*out_mapper);
  ASSERT_NO_FATAL_FAILURE(ValidateCreateHelper(**out_mapper, size));
}

template <bool NON_ROOT_VMAR>
void CreateAndMapHelper(fzl::ResizeableVmoMapper* inout_mapper, uint64_t size, const char* name,
                        zx_vm_option_t map_options = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
                        uint32_t cache_policy = 0) {
  fbl::RefPtr<fzl::VmarManager> manager;
  if (NON_ROOT_VMAR) {
    manager = fzl::VmarManager::Create(kNonRootVmarSize, nullptr, kNonRootVmarOpts);
    ASSERT_NOT_NULL(manager);
  }

  ASSERT_NOT_NULL(inout_mapper);
  zx_status_t status;
  status = inout_mapper->CreateAndMap(size, name, map_options, std::move(manager), cache_policy);
  ASSERT_EQ(status, ZX_OK);
  ASSERT_NO_FATAL_FAILURE(ValidateCreateHelper(*inout_mapper, size));
}

template <bool NON_ROOT_VMAR>
void MapHelper(fzl::ResizeableVmoMapper* inout_mapper, zx::vmo vmo, uint64_t size,
               zx_vm_option_t map_options = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE) {
  fbl::RefPtr<fzl::VmarManager> manager;
  if (NON_ROOT_VMAR) {
    manager = fzl::VmarManager::Create(kNonRootVmarSize, nullptr, kNonRootVmarOpts);
    ASSERT_NOT_NULL(manager);
  }

  ASSERT_NOT_NULL(inout_mapper);
  zx_status_t status;
  status = inout_mapper->Map(std::move(vmo), size, map_options, std::move(manager));
  ASSERT_EQ(status, ZX_OK);
  ASSERT_NO_FATAL_FAILURE(ValidateCreateHelper(*inout_mapper, size));
}

template <bool NON_ROOT_VMAR>
void CreateTest() {
  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(
      CreateHelper<NON_ROOT_VMAR>(&mapper, zx_system_get_page_size(), vmo_name));
}

template <bool NON_ROOT_VMAR>
void CreateAndMapTest() {
  fzl::ResizeableVmoMapper mapper;
  ASSERT_NO_FATAL_FAILURE(
      CreateAndMapHelper<NON_ROOT_VMAR>(&mapper, zx_system_get_page_size(), vmo_name));
}

template <bool NON_ROOT_VMAR>
void MapTest() {
  zx::vmo vmo;
  zx_status_t status;

  status = zx::vmo::create(zx_system_get_page_size(), 0, &vmo);
  ASSERT_EQ(status, ZX_OK);

  status = vmo.set_property(ZX_PROP_NAME, vmo_name, strlen(vmo_name));
  ASSERT_EQ(status, ZX_OK);

  fzl::ResizeableVmoMapper mapper;
  ASSERT_NO_FATAL_FAILURE(
      MapHelper<NON_ROOT_VMAR>(&mapper, std::move(vmo), zx_system_get_page_size()));
}

template <bool NON_ROOT_VMAR>
void MoveTest() {
  fzl::ResizeableVmoMapper mapper1;
  ASSERT_NO_FATAL_FAILURE(
      CreateAndMapHelper<NON_ROOT_VMAR>(&mapper1, zx_system_get_page_size(), vmo_name));

  // Move by construction
  zx_handle_t orig_handle = mapper1.vmo().get();
  void* orig_start = mapper1.start();
  size_t orig_size = mapper1.size();
  const fzl::VmarManager* orig_manager = mapper1.manager().get();

  ASSERT_NE(orig_handle, ZX_HANDLE_INVALID);
  ASSERT_NOT_NULL(orig_start);
  ASSERT_EQ(orig_size, zx_system_get_page_size());
  if (NON_ROOT_VMAR) {
    ASSERT_NOT_NULL(orig_manager);
  } else {
    ASSERT_NULL(orig_manager);
  }

  fzl::ResizeableVmoMapper mapper2(std::move(mapper1));
  ASSERT_EQ(mapper1.vmo().get(), ZX_HANDLE_INVALID);
  ASSERT_NULL(mapper1.start());
  ASSERT_EQ(mapper1.size(), 0);
  ASSERT_NULL(mapper1.manager());

  ASSERT_EQ(mapper2.vmo().get(), orig_handle);
  ASSERT_EQ(mapper2.start(), orig_start);
  ASSERT_EQ(mapper2.size(), orig_size);
  ASSERT_EQ(mapper2.manager().get(), orig_manager);
  ASSERT_NO_FATAL_FAILURE(ValidateCreateHelper(mapper2, orig_size));

  // Move by assignment
  mapper1 = std::move(mapper2);

  ASSERT_EQ(mapper2.vmo().get(), ZX_HANDLE_INVALID);
  ASSERT_NULL(mapper2.start());
  ASSERT_EQ(mapper2.size(), 0);
  ASSERT_NULL(mapper2.manager());

  ASSERT_EQ(mapper1.vmo().get(), orig_handle);
  ASSERT_EQ(mapper1.start(), orig_start);
  ASSERT_EQ(mapper1.size(), orig_size);
  ASSERT_EQ(mapper1.manager().get(), orig_manager);
  ASSERT_NO_FATAL_FAILURE(ValidateCreateHelper(mapper1, orig_size));
}

template <bool NON_ROOT_VMAR>
void ReadTest() {
  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(
      CreateHelper<NON_ROOT_VMAR>(&mapper, zx_system_get_page_size(), vmo_name));

  std::vector<uint8_t> bytes(zx_system_get_page_size());
  memset(bytes.data(), 0xff, zx_system_get_page_size());

  zx_status_t status = mapper->vmo().read(bytes.data(), 0, zx_system_get_page_size());
  ASSERT_EQ(status, ZX_OK);
  for (size_t i = 0; i < zx_system_get_page_size(); ++i) {
    ASSERT_EQ(bytes[i], 0);
  }
}

// Test that touching memory, then zx_vmo_reading, works as expected.
template <bool NON_ROOT_VMAR>
void WriteMappingTest() {
  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(
      CreateHelper<NON_ROOT_VMAR>(&mapper, zx_system_get_page_size(), vmo_name));

  auto data = static_cast<uint8_t*>(mapper->start());
  memset(data, 0xff, zx_system_get_page_size());

  std::vector<uint8_t> bytes(zx_system_get_page_size());
  zx_status_t status = mapper->vmo().read(bytes.data(), 0, zx_system_get_page_size());
  ASSERT_EQ(status, ZX_OK);
  for (size_t i = 0; i < zx_system_get_page_size(); ++i) {
    ASSERT_EQ(bytes[i], 0xff);
  }
}

// Test that zx_vmo_writing, then reading memory, works as expected.
template <bool NON_ROOT_VMAR>
void ReadMappingTest() {
  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(
      CreateHelper<NON_ROOT_VMAR>(&mapper, zx_system_get_page_size(), vmo_name));

  std::vector<uint8_t> bytes(zx_system_get_page_size());
  memset(bytes.data(), 0xff, zx_system_get_page_size());
  zx_status_t status = mapper->vmo().write(bytes.data(), 0, zx_system_get_page_size());
  ASSERT_EQ(status, ZX_OK);

  auto data = static_cast<uint8_t*>(mapper->start());
  for (size_t i = 0; i < zx_system_get_page_size(); ++i) {
    ASSERT_EQ(data[i], 0xff);
  }
}

template <bool NON_ROOT_VMAR>
void EmptyNameTest() {
  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(
      UncheckedCreateHelper<NON_ROOT_VMAR>(&mapper, zx_system_get_page_size(), ""));
  ASSERT_NOT_NULL(mapper);

  char name[ZX_MAX_NAME_LEN] = {};
  zx_status_t status = mapper->vmo().get_property(ZX_PROP_NAME, name, ZX_MAX_NAME_LEN);
  ASSERT_EQ(status, ZX_OK);
  for (size_t i = 0; i < ZX_MAX_NAME_LEN; ++i) {
    ASSERT_EQ(name[i], 0);
  }
}

template <bool NON_ROOT_VMAR>
void NullptrNameTest() {
  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(
      UncheckedCreateHelper<NON_ROOT_VMAR>(&mapper, zx_system_get_page_size(), nullptr));
  ASSERT_NOT_NULL(mapper);

  char name[ZX_MAX_NAME_LEN] = {};
  zx_status_t status = mapper->vmo().get_property(ZX_PROP_NAME, name, ZX_MAX_NAME_LEN);
  ASSERT_EQ(status, ZX_OK);
  for (size_t i = 0; i < ZX_MAX_NAME_LEN; ++i) {
    ASSERT_EQ(name[i], 0);
  }
}

template <bool NON_ROOT_VMAR>
void LongNameTest() {
  std::vector<char> long_name(zx_system_get_page_size());
  memset(long_name.data(), 'x', zx_system_get_page_size());
  long_name[zx_system_get_page_size() - 1] = 0;

  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(
      UncheckedCreateHelper<NON_ROOT_VMAR>(&mapper, zx_system_get_page_size(), long_name.data()));
  ASSERT_NOT_NULL(mapper);

  char name[ZX_MAX_NAME_LEN] = {};
  zx_status_t status = mapper->vmo().get_property(ZX_PROP_NAME, name, ZX_MAX_NAME_LEN);
  ASSERT_EQ(status, ZX_OK);
  for (size_t i = 0; i < ZX_MAX_NAME_LEN - 1; ++i) {
    ASSERT_EQ(name[i], 'x');
  }
  ASSERT_EQ(name[ZX_MAX_NAME_LEN - 1], 0);
}

template <bool NON_ROOT_VMAR>
void GoodSizesTest() {
  static const size_t sizes[] = {
      zx_system_get_page_size(),
      16 * zx_system_get_page_size(),
      zx_system_get_page_size() * zx_system_get_page_size(),
      zx_system_get_page_size() + 1,
  };

  for (size_t size : sizes) {
    std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
    ASSERT_NO_FATAL_FAILURE(CreateHelper<NON_ROOT_VMAR>(&mapper, size, vmo_name));
  }
}

template <bool NON_ROOT_VMAR>
void BadSizesTest() {
  // Size 0 should fail.
  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(UncheckedCreateHelper<NON_ROOT_VMAR>(&mapper, 0, vmo_name));
  ASSERT_NULL(mapper);

  // So should an aburdly big request.
  ASSERT_NO_FATAL_FAILURE(UncheckedCreateHelper<NON_ROOT_VMAR>(&mapper, SIZE_MAX, vmo_name));
  ASSERT_NULL(mapper);
}

template <bool NON_ROOT_VMAR>
void GoodShrinkTest() {
  size_t size = zx_system_get_page_size() * zx_system_get_page_size();

  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(CreateHelper<NON_ROOT_VMAR>(&mapper, size, vmo_name));

  while (size > 2 * zx_system_get_page_size()) {
    // The current size.
    zx_status_t status = mapper->Shrink(mapper->size());
    ASSERT_EQ(status, ZX_OK);
    ASSERT_EQ(mapper->size(), size);

    // A paged aligned size.
    size >>= 1;
    status = mapper->Shrink(size);
    ASSERT_EQ(status, ZX_OK);
    ASSERT_EQ(mapper->size(), size);
  }

  // TODO: Test that shrinking the map causes subsequent memory
  // accesses to fail.
}

template <bool NON_ROOT_VMAR>
void BadShrinkTest() {
  const size_t size = 16 * zx_system_get_page_size();

  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(CreateHelper<NON_ROOT_VMAR>(&mapper, size, vmo_name));

  // Shrinking to 0 should fail.
  zx_status_t status = mapper->Shrink(0);
  ASSERT_EQ(status, ZX_ERR_INVALID_ARGS);
  ASSERT_EQ(mapper->size(), size);

  // Growing via shrink should also fail.
  status = mapper->Shrink(2 * mapper->size());
  ASSERT_EQ(status, ZX_ERR_INVALID_ARGS);
  ASSERT_EQ(mapper->size(), size);

  // Growing to a misaligned size should also fail.
  status = mapper->Shrink(zx_system_get_page_size() + 23);
  ASSERT_EQ(status, ZX_ERR_INVALID_ARGS);
  ASSERT_EQ(mapper->size(), size);
}

template <bool NON_ROOT_VMAR>
void AlignedGoodGrowTest() {
  const size_t original_size = zx_system_get_page_size();
  const size_t grow_size = 2 * zx_system_get_page_size();

  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(CreateHelper<NON_ROOT_VMAR>(&mapper, original_size, vmo_name));

  // Growing to the current size should always succeed.
  zx_status_t status = mapper->Grow(mapper->size());
  ASSERT_EQ(status, ZX_OK);

  status = mapper->Grow(grow_size);
  if (status == ZX_OK) {
    ASSERT_EQ(mapper->size(), grow_size);
    // Check the last byte.
    auto data = static_cast<const uint8_t*>(mapper->start());
    ASSERT_EQ(data[grow_size - 1], 0);
  } else {
    // We might just get unlucky and get a zx_system_get_page_size() adjacent to
    // something and not be able to grow. If so, assert that the
    // size did not change.
    ASSERT_EQ(mapper->size(), original_size);
  }
}

template <bool NON_ROOT_VMAR>
void UnalignedGoodGrowTest() {
  const size_t original_size = zx_system_get_page_size();
  const size_t grow_size = 2 * zx_system_get_page_size() + 1;
  const size_t rounded_grow_size = 3 * zx_system_get_page_size();

  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(CreateHelper<NON_ROOT_VMAR>(&mapper, original_size, vmo_name));

  // Growing to the current size should always succeed.
  zx_status_t status = mapper->Grow(mapper->size());
  ASSERT_EQ(status, ZX_OK);

  status = mapper->Grow(grow_size);
  if (status == ZX_OK) {
    ASSERT_EQ(mapper->size(), rounded_grow_size);
    // Check the last byte.
    auto data = static_cast<const uint8_t*>(mapper->start());
    ASSERT_EQ(data[grow_size - 1], 0);
  } else {
    // We might just get unlucky and get a zx_system_get_page_size() adjacent to
    // something and not be able to grow. If so, assert that the
    // size did not change.
    ASSERT_EQ(mapper->size(), original_size);
  }
}

template <bool NON_ROOT_VMAR>
void BadGrowTest() {
  const size_t original_size = 2 * zx_system_get_page_size();
  const size_t grow_size = zx_system_get_page_size();

  std::unique_ptr<fzl::ResizeableVmoMapper> mapper;
  ASSERT_NO_FATAL_FAILURE(CreateHelper<NON_ROOT_VMAR>(&mapper, original_size, vmo_name));

  // Growing from 2 pages to 1 should fail.
  zx_status_t status = mapper->Grow(grow_size);
  ASSERT_EQ(status, ZX_ERR_INVALID_ARGS);
  ASSERT_EQ(mapper->size(), original_size);

  // Growing from 2 pages to nothing should also fail.
  status = mapper->Grow(0);
  ASSERT_EQ(status, ZX_ERR_INVALID_ARGS);
  ASSERT_EQ(mapper->size(), original_size);
}

}  // namespace

#define MAKE_TEST(_name)                                               \
  TEST(ResizeableVmoMapperTests, _name##_RootVmar) { _name<false>(); } \
  TEST(ResizeableVmoMapperTests, _name##_NON_ROOT_VMAR) { _name<true>(); }

MAKE_TEST(CreateTest)
MAKE_TEST(CreateAndMapTest)
MAKE_TEST(MapTest)
MAKE_TEST(MoveTest)
MAKE_TEST(ReadTest)
MAKE_TEST(WriteMappingTest)
MAKE_TEST(ReadMappingTest)
MAKE_TEST(EmptyNameTest)
MAKE_TEST(NullptrNameTest)
MAKE_TEST(LongNameTest)
MAKE_TEST(GoodSizesTest)
MAKE_TEST(BadSizesTest)
MAKE_TEST(GoodShrinkTest)
MAKE_TEST(BadShrinkTest)
MAKE_TEST(AlignedGoodGrowTest)
MAKE_TEST(UnalignedGoodGrowTest)
MAKE_TEST(BadGrowTest)

#undef MAKE_TEST
