//===- ExecutionSessionWrapperFunctionCallsTest.cpp -- Test wrapper calls -===//
//
// 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/Core.h"
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
#include "llvm/Support/MSVCErrorWorkarounds.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"

#include <future>

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

static llvm::orc::shared::CWrapperFunctionResult addWrapper(const char *ArgData,
                                                            size_t ArgSize) {
  return WrapperFunction<int32_t(int32_t, int32_t)>::handle(
             ArgData, ArgSize, [](int32_t X, int32_t Y) { return X + Y; })
      .release();
}

static void addAsyncWrapper(unique_function<void(int32_t)> SendResult,
                            int32_t X, int32_t Y) {
  SendResult(X + Y);
}

static llvm::orc::shared::CWrapperFunctionResult
voidWrapper(const char *ArgData, size_t ArgSize) {
  return WrapperFunction<void()>::handle(ArgData, ArgSize, []() {}).release();
}

TEST(ExecutionSessionWrapperFunctionCalls, RunWrapperTemplate) {
  ExecutionSession ES(cantFail(SelfExecutorProcessControl::Create()));

  int32_t Result;
  EXPECT_THAT_ERROR(ES.callSPSWrapper<int32_t(int32_t, int32_t)>(
                        ExecutorAddr::fromPtr(addWrapper), Result, 2, 3),
                    Succeeded());
  EXPECT_EQ(Result, 5);
  cantFail(ES.endSession());
}

TEST(ExecutionSessionWrapperFunctionCalls, RunVoidWrapperAsyncTemplate) {
  ExecutionSession ES(cantFail(SelfExecutorProcessControl::Create()));

  std::promise<MSVCPError> RP;
  ES.callSPSWrapperAsync<void()>(ExecutorAddr::fromPtr(voidWrapper),
                                 [&](Error SerializationErr) {
                                   RP.set_value(std::move(SerializationErr));
                                 });
  Error Err = RP.get_future().get();
  EXPECT_THAT_ERROR(std::move(Err), Succeeded());
  cantFail(ES.endSession());
}

TEST(ExecutionSessionWrapperFunctionCalls, RunNonVoidWrapperAsyncTemplate) {
  ExecutionSession ES(cantFail(SelfExecutorProcessControl::Create()));

  std::promise<MSVCPExpected<int32_t>> RP;
  ES.callSPSWrapperAsync<int32_t(int32_t, int32_t)>(
      ExecutorAddr::fromPtr(addWrapper),
      [&](Error SerializationErr, int32_t R) {
        if (SerializationErr)
          RP.set_value(std::move(SerializationErr));
        RP.set_value(std::move(R));
      },
      2, 3);
  Expected<int32_t> Result = RP.get_future().get();
  EXPECT_THAT_EXPECTED(Result, HasValue(5));
  cantFail(ES.endSession());
}

TEST(ExecutionSessionWrapperFunctionCalls, RegisterAsyncHandlerAndRun) {

  constexpr ExecutorAddr AddAsyncTagAddr(0x01);

  ExecutionSession ES(cantFail(SelfExecutorProcessControl::Create()));
  auto &JD = ES.createBareJITDylib("JD");

  auto AddAsyncTag = ES.intern("addAsync_tag");
  cantFail(JD.define(absoluteSymbols(
      {{AddAsyncTag, {AddAsyncTagAddr, JITSymbolFlags::Exported}}})));

  ExecutionSession::JITDispatchHandlerAssociationMap Associations;

  Associations[AddAsyncTag] =
      ES.wrapAsyncWithSPS<int32_t(int32_t, int32_t)>(addAsyncWrapper);

  cantFail(ES.registerJITDispatchHandlers(JD, std::move(Associations)));

  std::promise<int32_t> RP;
  auto RF = RP.get_future();

  using ArgSerialization = SPSArgList<int32_t, int32_t>;
  size_t ArgBufferSize = ArgSerialization::size(1, 2);
  auto ArgBuffer = WrapperFunctionResult::allocate(ArgBufferSize);
  SPSOutputBuffer OB(ArgBuffer.data(), ArgBuffer.size());
  EXPECT_TRUE(ArgSerialization::serialize(OB, 1, 2));

  ES.runJITDispatchHandler(
      [&](WrapperFunctionResult ResultBuffer) {
        int32_t Result;
        SPSInputBuffer IB(ResultBuffer.data(), ResultBuffer.size());
        EXPECT_TRUE(SPSArgList<int32_t>::deserialize(IB, Result));
        RP.set_value(Result);
      },
      AddAsyncTagAddr, ArrayRef<char>(ArgBuffer.data(), ArgBuffer.size()));

  EXPECT_EQ(RF.get(), (int32_t)3);

  cantFail(ES.endSession());
}
