// Copyright 2023 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/trivial-allocator/posix.h>
#include <lib/trivial-allocator/sealed-page-allocator.h>

#ifdef __Fuchsia__
#include <lib/trivial-allocator/zircon.h>
#endif

#include <array>

#include <gtest/gtest.h>

namespace {

template <class Memory, size_t Reserve, typename... Args>
void SealedPageAllocatorTestWithReserve(Args&&... args) {
  trivial_allocator::SealedPageAllocator<Memory, Reserve> allocator(args...);

  auto& memory = allocator.memory();
  static_assert(std::is_same_v<decltype(memory), Memory&>);

  const auto& const_allocator = allocator;
  auto& const_memory = const_allocator.memory();
  static_assert(std::is_same_v<decltype(const_memory), const Memory&>);

  const size_t pagesize = const_memory.page_size();

  struct Live {
    decltype(allocator(std::declval<size_t&>(), size_t{})) allocation;
    int* ptr = nullptr;
  };

  // The allocator should keep exactly this many released allocations writable.
  constexpr size_t kUnsealedCount = Reserve + 1;

  std::array<Live, kUnsealedCount> live;

  for (auto& l : live) {
    size_t size = 1;
    l.allocation = allocator(size, 1);
    EXPECT_TRUE(l.allocation);
    EXPECT_EQ(pagesize, size);
    int* iptr = reinterpret_cast<int*>(l.allocation.get());
    EXPECT_EQ(0, *iptr);
    *iptr = 17;

    l.ptr = reinterpret_cast<int*>(l.allocation.release());
    EXPECT_EQ(iptr, l.ptr);
  }

  // After all those are released, they should still be writable.
  for (auto& l : live) {
    volatile int* vptr = l.ptr;
    EXPECT_EQ(17, *vptr);
    *vptr = 23;
  }
  for (auto& l : live) {
    EXPECT_EQ(23, *l.ptr);
  }

  // These allocations should push all those out so they get sealed.
  std::array<Live, kUnsealedCount> extra;
  for (auto& l : extra) {
    size_t size = 1;
    l.allocation = allocator(size, 1);
    EXPECT_TRUE(l.allocation);
    EXPECT_EQ(pagesize, size);
    int* iptr = reinterpret_cast<int*>(l.allocation.get());
    EXPECT_EQ(0, *iptr);
    *iptr = 17;

    l.ptr = reinterpret_cast<int*>(l.allocation.release());
    EXPECT_EQ(iptr, l.ptr);
  }

  // The old pointers should now be read-only.
  for (auto& l : live) {
    volatile int* vptr = l.ptr;
    EXPECT_EQ(23, *vptr);
    EXPECT_DEATH({ *vptr = 42; }, "") << "unsealed count " << kUnsealedCount;
  }

  // Finish off the allocator so everything is sealed.
  std::move(allocator).Seal();

  // These pointers should now be sealed too.
  for (auto& l : extra) {
    volatile int* vptr = l.ptr;
    EXPECT_EQ(17, *vptr);
    EXPECT_DEATH({ *vptr = 23; }, "");
  }

  // Allocate and release some pages but don't seal them.
  for (auto& l : live) {
    size_t size = 1;
    l.allocation = allocator(size, 1);
    EXPECT_TRUE(l.allocation);
    EXPECT_EQ(pagesize, size);
    int* iptr = reinterpret_cast<int*>(l.allocation.get());
    EXPECT_EQ(0, *iptr);
    *iptr = 17;

    l.ptr = reinterpret_cast<int*>(l.allocation.release());
    EXPECT_EQ(iptr, l.ptr);
  }

  // Get a fresh allocator instance and some fresh allocations.
  allocator = decltype(allocator)(args...);
  for (auto& l : live) {
    size_t size = 1;
    l.allocation = allocator(size, 1);
    EXPECT_TRUE(l.allocation);
    EXPECT_EQ(pagesize, size);
    int* iptr = reinterpret_cast<int*>(l.allocation.get());
    EXPECT_EQ(0, *iptr);
    *iptr = 17;

    l.ptr = reinterpret_cast<int*>(l.allocation.release());
    EXPECT_EQ(iptr, l.ptr);
  }

  // Destroy the allocator without sealing.
  allocator = decltype(allocator)();

  // All those live allocations should have been unmapped.
  for (auto& l : live) {
    volatile int* vptr = l.ptr;
    EXPECT_DEATH({ *vptr = 42; }, "");
  }
}

template <class Memory, typename... Args>
void SealedPageAllocatorTest(Args&&... args) {
  SealedPageAllocatorTestWithReserve<Memory, 0>(args...);
  SealedPageAllocatorTestWithReserve<Memory, 1>(args...);
  SealedPageAllocatorTestWithReserve<Memory, 2>(args...);
  SealedPageAllocatorTestWithReserve<Memory, 3>(args...);
}

TEST(TrivialAllocatorTests, SealedPageAllocatorMmap) {
  ASSERT_NO_FATAL_FAILURE(SealedPageAllocatorTest<trivial_allocator::PosixMmap>());
}

#ifdef __Fuchsia__

TEST(TrivialAllocatorTests, SealedPageAllocatorVmar) {
  ASSERT_NO_FATAL_FAILURE(
      SealedPageAllocatorTest<trivial_allocator::ZirconVmar>(*zx::vmar::root_self()));
}

#endif

}  // namespace
