//===------------------------ MemoryMapperTest.cpp ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/Orc/MemoryMapper.h"
#include "llvm/Support/Process.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"

using namespace llvm;
using namespace llvm::orc;
using namespace llvm::orc::shared;

namespace {

Expected<ExecutorAddrRange> reserve(MemoryMapper &M, size_t NumBytes) {
  std::promise<MSVCPExpected<ExecutorAddrRange>> P;
  auto F = P.get_future();
  M.reserve(NumBytes, [&](auto R) { P.set_value(std::move(R)); });
  return F.get();
}

Expected<ExecutorAddr> initialize(MemoryMapper &M,
                                  MemoryMapper::AllocInfo &AI) {
  std::promise<MSVCPExpected<ExecutorAddr>> P;
  auto F = P.get_future();
  M.initialize(AI, [&](auto R) { P.set_value(std::move(R)); });
  return F.get();
}

Error deinitialize(MemoryMapper &M,
                   const std::vector<ExecutorAddr> &Allocations) {
  std::promise<MSVCPError> P;
  auto F = P.get_future();
  M.deinitialize(Allocations, [&](auto R) { P.set_value(std::move(R)); });
  return F.get();
}

Error release(MemoryMapper &M, const std::vector<ExecutorAddr> &Reservations) {
  std::promise<MSVCPError> P;
  auto F = P.get_future();
  M.release(Reservations, [&](auto R) { P.set_value(std::move(R)); });
  return F.get();
}

// A basic function to be used as both initializer/deinitializer
orc::shared::CWrapperFunctionResult incrementWrapper(const char *ArgData,
                                                     size_t ArgSize) {
  return WrapperFunction<SPSError(SPSExecutorAddr)>::handle(
             ArgData, ArgSize,
             [](ExecutorAddr A) -> Error {
               *A.toPtr<int *>() += 1;
               return Error::success();
             })
      .release();
}

TEST(MemoryMapperTest, InitializeDeinitialize) {
  // These counters are used to track how many times the initializer and
  // deinitializer functions are called
  int InitializeCounter = 0;
  int DeinitializeCounter = 0;
  {
    std::unique_ptr<MemoryMapper> Mapper =
        cantFail(InProcessMemoryMapper::Create());

    // We will do two separate allocations
    auto PageSize = Mapper->getPageSize();
    auto TotalSize = PageSize * 2;

    // Reserve address space
    auto Mem1 = reserve(*Mapper, TotalSize);
    EXPECT_THAT_ERROR(Mem1.takeError(), Succeeded());

    // Test string for memory transfer
    std::string HW = "Hello, world!";

    {
      // Provide working memory
      char *WA1 = Mapper->prepare(Mem1->Start, HW.size() + 1);
      std::strcpy(static_cast<char *>(WA1), HW.c_str());
    }

    // A structure to be passed to initialize
    MemoryMapper::AllocInfo Alloc1;
    {
      MemoryMapper::AllocInfo::SegInfo Seg1;
      Seg1.Offset = 0;
      Seg1.ContentSize = HW.size();
      Seg1.ZeroFillSize = PageSize - Seg1.ContentSize;
      Seg1.AG = MemProt::Read | MemProt::Write;

      Alloc1.MappingBase = Mem1->Start;
      Alloc1.Segments.push_back(Seg1);
      Alloc1.Actions.push_back(
          {cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
               ExecutorAddr::fromPtr(incrementWrapper),
               ExecutorAddr::fromPtr(&InitializeCounter))),
           cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
               ExecutorAddr::fromPtr(incrementWrapper),
               ExecutorAddr::fromPtr(&DeinitializeCounter)))});
    }

    {
      char *WA2 = Mapper->prepare(Mem1->Start + PageSize, HW.size() + 1);
      std::strcpy(static_cast<char *>(WA2), HW.c_str());
    }

    MemoryMapper::AllocInfo Alloc2;
    {
      MemoryMapper::AllocInfo::SegInfo Seg2;
      Seg2.Offset = PageSize;
      Seg2.ContentSize = HW.size();
      Seg2.ZeroFillSize = PageSize - Seg2.ContentSize;
      Seg2.AG = MemProt::Read | MemProt::Write;

      Alloc2.MappingBase = Mem1->Start;
      Alloc2.Segments.push_back(Seg2);
      Alloc2.Actions.push_back(
          {cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
               ExecutorAddr::fromPtr(incrementWrapper),
               ExecutorAddr::fromPtr(&InitializeCounter))),
           cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
               ExecutorAddr::fromPtr(incrementWrapper),
               ExecutorAddr::fromPtr(&DeinitializeCounter)))});
    }

    EXPECT_EQ(InitializeCounter, 0);
    EXPECT_EQ(DeinitializeCounter, 0);

    // Set memory protections and run initializers
    auto Init1 = initialize(*Mapper, Alloc1);
    EXPECT_THAT_ERROR(Init1.takeError(), Succeeded());
    EXPECT_EQ(HW, std::string(static_cast<char *>(Init1->toPtr<char *>())));

    EXPECT_EQ(InitializeCounter, 1);
    EXPECT_EQ(DeinitializeCounter, 0);

    auto Init2 = initialize(*Mapper, Alloc2);
    EXPECT_THAT_ERROR(Init2.takeError(), Succeeded());
    EXPECT_EQ(HW, std::string(static_cast<char *>(Init2->toPtr<char *>())));

    EXPECT_EQ(InitializeCounter, 2);
    EXPECT_EQ(DeinitializeCounter, 0);

    // Explicit deinitialization of first allocation
    std::vector<ExecutorAddr> DeinitAddr = {*Init1};
    EXPECT_THAT_ERROR(deinitialize(*Mapper, DeinitAddr), Succeeded());

    EXPECT_EQ(InitializeCounter, 2);
    EXPECT_EQ(DeinitializeCounter, 1);

    // Test explicit release
    {
      auto Mem2 = reserve(*Mapper, PageSize);
      EXPECT_THAT_ERROR(Mem2.takeError(), Succeeded());

      char *WA = Mapper->prepare(Mem2->Start, HW.size() + 1);
      std::strcpy(static_cast<char *>(WA), HW.c_str());

      MemoryMapper::AllocInfo Alloc3;
      {
        MemoryMapper::AllocInfo::SegInfo Seg3;
        Seg3.Offset = 0;
        Seg3.ContentSize = HW.size();
        Seg3.ZeroFillSize = PageSize - Seg3.ContentSize;
        Seg3.AG = MemProt::Read | MemProt::Write;

        Alloc3.MappingBase = Mem2->Start;
        Alloc3.Segments.push_back(Seg3);
        Alloc3.Actions.push_back(
            {cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
                 ExecutorAddr::fromPtr(incrementWrapper),
                 ExecutorAddr::fromPtr(&InitializeCounter))),
             cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
                 ExecutorAddr::fromPtr(incrementWrapper),
                 ExecutorAddr::fromPtr(&DeinitializeCounter)))});
      }
      auto Init3 = initialize(*Mapper, Alloc3);
      EXPECT_THAT_ERROR(Init3.takeError(), Succeeded());
      EXPECT_EQ(HW, std::string(static_cast<char *>(Init3->toPtr<char *>())));

      EXPECT_EQ(InitializeCounter, 3);
      EXPECT_EQ(DeinitializeCounter, 1);

      std::vector<ExecutorAddr> ReleaseAddrs = {Mem2->Start};
      EXPECT_THAT_ERROR(release(*Mapper, ReleaseAddrs), Succeeded());

      EXPECT_EQ(InitializeCounter, 3);
      EXPECT_EQ(DeinitializeCounter, 2);
    }
  }

  // Implicit deinitialization by the destructor
  EXPECT_EQ(InitializeCounter, 3);
  EXPECT_EQ(DeinitializeCounter, 3);
}

} // namespace
