//===- SessionTest.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
//
//===----------------------------------------------------------------------===//
//
// Tests for orc-rt's Session.h APIs.
//
//===----------------------------------------------------------------------===//

#include "orc-rt/Session.h"
#include "orc-rt/QueueingRunner.h"
#include "orc-rt/SPSWrapperFunction.h"

#include "orc-rt-c/Session.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "CommonTestUtils.h"

#include <chrono>
#include <deque>
#include <future>
#include <optional>

using namespace orc_rt;
using ::testing::Eq;
using ::testing::Optional;

class MockService : public Service {
public:
  enum class Op { Detach, Shutdown };

  static void noop(Op) {}

  MockService(std::optional<size_t> &DetachOpIdx,
              std::optional<size_t> &ShutdownOpIdx, size_t &OpIdx,
              move_only_function<void(Op)> GenResult = noop)
      : DetachOpIdx(DetachOpIdx), ShutdownOpIdx(ShutdownOpIdx), OpIdx(OpIdx),
        GenResult(std::move(GenResult)) {}

  void onDetach(OnCompleteFn OnComplete, bool ShutdownRequested) override {
    DetachOpIdx = OpIdx++;
    GenResult(Op::Detach);
    OnComplete();
  }

  void onShutdown(OnCompleteFn OnComplete) override {
    ShutdownOpIdx = OpIdx++;
    GenResult(Op::Shutdown);
    OnComplete();
  }

private:
  std::optional<size_t> &DetachOpIdx;
  std::optional<size_t> &ShutdownOpIdx;
  size_t &OpIdx;
  move_only_function<void(Op)> GenResult;
};

class ConfigurableService : public Service {
public:
  ConfigurableService(int ConstructorOption) {}

  /// Fallible named constructor for testing tryCreateService.
  static Expected<std::unique_ptr<ConfigurableService>> Create(bool Fail) {
    if (Fail)
      return make_error<StringError>("failed to create service");
    return std::make_unique<ConfigurableService>(42);
  }

  void onDetach(OnCompleteFn OnComplete, bool ShutdownRequested) override {
    OnComplete();
  }

  void onShutdown(OnCompleteFn OnComplete) override { OnComplete(); }

  void doMoreConfig(int) noexcept {}
};

class MockControllerAccess : public Session::ControllerAccess {

private:
  class ConnectGuard {
  public:
    ConnectGuard() = default;
    ConnectGuard(MockControllerAccess *MCA) : MCA(MCA) {
      // Note: Assumes already locked.
      ++MCA->Outstanding;
    }
    ConnectGuard(const ConnectGuard &) = delete;
    ConnectGuard &operator=(const ConnectGuard &) = delete;
    ConnectGuard(ConnectGuard &&Other) : MCA(Other.MCA) { Other.MCA = nullptr; }
    ConnectGuard &operator=(ConnectGuard &&Other) {
      reset();
      MCA = Other.MCA;
      Other.MCA = nullptr;
      return *this;
    };
    ~ConnectGuard() { reset(); }

  private:
    void reset() {
      if (MCA) {
        bool Notify;
        {
          std::scoped_lock Lock(MCA->M);
          --MCA->Outstanding;
          Notify = MCA->Shutdown && MCA->Outstanding == 0;
        }
        if (Notify)
          MCA->ShutdownCV.notify_all();
      }
    }
    MockControllerAccess *MCA = nullptr;
  };

public:
  using OnConnectFn = move_only_function<Error(BootstrapInfo &BI)>;

  /// Hook used to defer controller-side work (the simulated controller
  /// handler invocation, and the OnComplete callback for completed calls).
  /// Tests typically wire this to push onto the same WorkQueue that the
  /// Session's QueueingRunner uses, so that a single drain advances both
  /// sides.
  using PostFn = move_only_function<void(move_only_function<void()>)>;

  MockControllerAccess(Session &SS, PostFn Post = {},
                       OnConnectFn OnConnect = {},
                       MockControllerAccess **Self = nullptr)
      : Session::ControllerAccess(SS), Post(std::move(Post)),
        OnConnect(std::move(OnConnect)) {
    // Optionally publish this instance so tests that need to drive the
    // controller side directly can reach it after attach constructs it.
    // (attach constructs the ControllerAccess internally and does not hand
    // back a reference, since the object may not outlive the attach call.)
    if (Self)
      *Self = this;
  }

  /// Fallible named constructor for testing tryAttach. Returns an error if
  /// Fail is true, otherwise a MockControllerAccess forwarding the remaining
  /// arguments to the constructor.
  static Expected<std::shared_ptr<MockControllerAccess>>
  Create(Session &S, bool Fail, PostFn Post = {}, OnConnectFn OnConnect = {}) {
    if (Fail)
      return make_error<StringError>("failed to create controller access");
    return std::make_shared<MockControllerAccess>(S, std::move(Post),
                                                  std::move(OnConnect));
  }

  void connect(BootstrapInfo BI) override {
    if (OnConnect) {
      if (auto Err = OnConnect(BI)) {
        reportError(std::move(Err));
        notifyDisconnected();
      }
    }
  }

  void disconnect() override {
    // Drain any still-pending controller calls before notifying, so their
    // handlers are failed rather than silently dropped -- see the
    // ControllerAccess::disconnect contract. Shutdown gates callController
    // (which bails via failControllerCallInline once it is set), so no new call
    // can be registered after the snapshot below.
    std::unordered_map<size_t, OnControllerCallReturn> ToDrain;
    {
      std::unique_lock<std::mutex> Lock(M);
      Shutdown = true;
      ShutdownCV.wait(Lock, [this]() { return Shutdown && Outstanding == 0; });
      ToDrain = std::move(PendingOut);
    }
    for (auto &[_, OnComplete] : ToDrain)
      failPendingControllerCall(std::move(OnComplete));
    notifyDisconnected();
  }

  void callController(OnControllerCallReturn OnComplete,
                      orc_rt_ControllerHandlerTag T,
                      WrapperFunctionBuffer ArgBytes) override {
    // Simulate a call to the controller by running the requested function via
    // the test-supplied Post hook (or inline, if no hook was provided).
    ConnectGuard CG;
    size_t CId = 0;
    bool BailOut = false;
    {
      std::scoped_lock<std::mutex> Lock(M);
      if (!Shutdown) {
        CG = ConnectGuard(this);
        CId = CallId++;
        assert(!PendingOut.count(CId));
        PendingOut[CId] = std::move(OnComplete);
      } else
        BailOut = true;
    }

    if (BailOut)
      return failControllerCallInline(std::move(OnComplete));

    runOrPost([this, CId, T, ArgBytes = std::move(ArgBytes)]() mutable {
      auto Fn = reinterpret_cast<orc_rt_WrapperFunction>(T);
      Fn(reinterpret_cast<orc_rt_SessionRef>(this), ArgBytes.release(),
         ccReturn, CId);
    });
  }

  void sendWrapperResult(WrapperFunctionBuffer ResultBytes,
                         uint64_t CallId) override {
    // Respond to a simulated call by the controller.
    ConnectGuard CG;
    Session::OnControllerCallReturnFn OnComplete;
    {
      std::scoped_lock<std::mutex> Lock(M);
      if (Shutdown) {
        assert(PendingIn.empty() && "Shut down but results still pending?");
        return;
      }
      CG = ConnectGuard(this);
      auto I = PendingIn.find(CallId);
      assert(I != PendingIn.end());
      OnComplete = std::move(I->second);
      PendingIn.erase(I);
    }

    runOrPost([OnComplete = std::move(OnComplete),
               ResultBytes = std::move(ResultBytes)]() mutable {
      OnComplete(std::move(ResultBytes));
    });
  }

  void returnFromController(uint64_t CallId,
                            WrapperFunctionBuffer ResultBytes) {
    ConnectGuard CG;
    OnControllerCallReturn OnComplete;
    {
      std::scoped_lock<std::mutex> Lock(M);
      CG = ConnectGuard(this);
      auto I = PendingOut.find(CallId);
      assert(I != PendingOut.end());
      OnComplete = std::move(I->second);
      PendingOut.erase(I);
    }

    handleControllerCallResult(std::move(OnComplete), std::move(ResultBytes));
  }

  void callFromController(Session::OnControllerCallReturnFn OnComplete,
                          orc_rt_WrapperFunction Fn,
                          WrapperFunctionBuffer ArgBytes) {
    ConnectGuard CG;
    size_t CId = 0;
    bool BailOut = false;
    {
      std::scoped_lock<std::mutex> Lock(M);
      if (!Shutdown) {
        CG = ConnectGuard(this);
        CId = CallId++;
        PendingIn[CId] = std::move(OnComplete);
      } else
        BailOut = true;
    }
    if (BailOut)
      return runOrPost([OnComplete = std::move(OnComplete)]() mutable {
        OnComplete(WrapperFunctionBuffer::createOutOfBandError(
            "Controller disconnected"));
      });

    handleWrapperCall(Fn, std::move(ArgBytes), CId);
  }

private:
  void runOrPost(move_only_function<void()> Work) {
    if (Post)
      Post(std::move(Work));
    else
      Work();
  }

  static void ccReturn(orc_rt_SessionRef S,
                       orc_rt_WrapperFunctionBuffer ResultBytes,
                       uint64_t CallId) {
    // Abuse "session" to refer to the ControllerAccess object.
    // We can just re-use sendFunctionResult for this.
    reinterpret_cast<MockControllerAccess *>(S)->returnFromController(
        CallId, WrapperFunctionBuffer(ResultBytes));
  }

  PostFn Post;

  std::mutex M;
  bool Shutdown = false;
  size_t CallId = 0;
  size_t Outstanding = 0;
  std::unordered_map<size_t, OnControllerCallReturn> PendingOut;
  std::unordered_map<size_t, Session::OnControllerCallReturnFn> PendingIn;
  std::condition_variable ShutdownCV;
  OnConnectFn OnConnect;
};

class CallFromController {
public:
  CallFromController(MockControllerAccess &CA, orc_rt_WrapperFunction Fn)
      : CA(CA), Fn(Fn) {}
  void operator()(Session::OnControllerCallReturnFn OnComplete,
                  WrapperFunctionBuffer ArgBytes) {
    CA.callFromController(std::move(OnComplete), Fn, std::move(ArgBytes));
  }

private:
  MockControllerAccess &CA;
  orc_rt_WrapperFunction Fn;
};

/// Build a PostFn for MockControllerAccess that pushes its work onto the
/// supplied queue. With this, a single QueueingRunner::runFIFOUntilEmpty(Q)
/// call advances both Session-side and controller-side work.
inline MockControllerAccess::PostFn postOnto(QueueingRunner<>::WorkQueue &Q) {
  return
      [&Q](move_only_function<void()> Work) { Q.push_back(std::move(Work)); };
}

void waitForShutdown(Session &S) {
  std::promise<void> P;
  auto F = P.get_future();
  S.shutdown([P = std::move(P)]() mutable { P.set_value(); });
  F.get();
}

TEST(SessionTest, TrivialConstructionAndDestruction) {
  Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
}

TEST(SessionTest, ReportError) {
  Error E = Error::success();
  cantFail(std::move(E)); // Force error into checked state.

  Session S(mockExecutorProcessInfo(), noDispatch,
            [&](Error Err) { E = std::move(Err); });
  S.reportError(make_error<StringError>("foo"));

  if (E)
    EXPECT_EQ(toString(std::move(E)), "foo");
  else
    ADD_FAILURE() << "Missing error value";
}

TEST(SessionTest, ReportErrorsViaSession) {
  Error E = Error::success();
  cantFail(std::move(E)); // Force error into checked state.

  // Check that the ReportErrorsViaSession utility works as advertised.
  Session S(mockExecutorProcessInfo(), noDispatch,
            [&](Error Err) { E = std::move(Err); });
  (ReportErrorsViaSession(S))(make_error<StringError>("foo"));

  if (E)
    EXPECT_EQ(toString(std::move(E)), "foo");
  else
    ADD_FAILURE() << "Missing error value";
}

TEST(SessionTest, SingleService) {
  size_t OpIdx = 0;
  std::optional<size_t> DetachOpIdx;
  std::optional<size_t> ShutdownOpIdx;

  {
    Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
    S.addService(
        std::make_unique<MockService>(DetachOpIdx, ShutdownOpIdx, OpIdx));
  }

  EXPECT_EQ(OpIdx, 2U);
  EXPECT_EQ(DetachOpIdx, 0U);
  EXPECT_EQ(ShutdownOpIdx, 1U);
}

TEST(SessionTest, MultipleServices) {
  size_t OpIdx = 0;
  std::optional<size_t> DetachOpIdx[3];
  std::optional<size_t> ShutdownOpIdx[3];

  {
    Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
    for (size_t I = 0; I != 3; ++I)
      S.addService(std::make_unique<MockService>(DetachOpIdx[I],
                                                 ShutdownOpIdx[I], OpIdx));
  }

  EXPECT_EQ(OpIdx, 6U);
  // Expect shutdown in reverse order.
  for (size_t I = 0; I != 3; ++I) {
    EXPECT_EQ(DetachOpIdx[I], 2 - I);
    EXPECT_EQ(ShutdownOpIdx[I], 5 - I);
  }
}

TEST(SessionTest, ScheduleShutdownFromOnDetachHandler) {
  // Check that when we schedule a shutdown from an onDetach handler:
  // 1. The shutdown is scheduled.
  // 2. All onDetach handlers run before any onShutdown handlers.

  Session S(mockExecutorProcessInfo(), noDispatch, noErrors);

  int OnDetachHandlersRun = 0;
  bool OnShutdownHandlerRun = false;

  S.addOnDetach([&]() { ++OnDetachHandlersRun; });
  S.addOnDetach([&]() { S.shutdown(); });
  S.addOnDetach([&]() { ++OnDetachHandlersRun; });
  S.addOnShutdown([&]() {
    EXPECT_EQ(OnDetachHandlersRun, 2);
    OnShutdownHandlerRun = true;
  });

  S.detach();

  EXPECT_TRUE(OnShutdownHandlerRun);
}

TEST(SessionTest, RedundantAsyncShutdown) {
  // Check that redundant calls to shutdown have their callbacks run.
  QueueingRunner<>::WorkQueue Tasks;
  Session S(mockExecutorProcessInfo(), QueueingRunner(Tasks), noErrors);

  // Initiate shutdown here, and wait for the on-shutdown callbacks to start
  // running.
  waitForShutdown(S);

  // Now try to add a new on-shutdown callback and verify that it runs.
  bool RedundantCallbackRan = false;
  S.shutdown([&]() { RedundantCallbackRan = true; });
  EXPECT_TRUE(RedundantCallbackRan);
}

TEST(SessionTest, ExpectedShutdownSequenceWithNoActiveManagedCodeCalls) {
  // Check that Session shutdown results in...
  // 1. Services being shut down.
  // 2. A call to OnShutdownComplete.

  size_t OpIdx = 0;
  std::optional<size_t> DetachOpIdx;
  std::optional<size_t> ShutdownOpIdx;
  bool SessionShutdownComplete = false;

  {
    QueueingRunner<>::WorkQueue Tasks;
    Session S(mockExecutorProcessInfo(), QueueingRunner(Tasks), noErrors);
    S.addService(
        std::make_unique<MockService>(DetachOpIdx, ShutdownOpIdx, OpIdx));

    S.shutdown([&]() {
      EXPECT_TRUE(ShutdownOpIdx);
      EXPECT_EQ(*ShutdownOpIdx, 1);
      SessionShutdownComplete = true;
    });
  }

  EXPECT_TRUE(SessionShutdownComplete);
}

TEST(SessionTest, ActiveManagedCallsDelayShutdown) {
  QueueingRunner<>::WorkQueue Tasks;
  Session S(mockExecutorProcessInfo(), QueueingRunner(Tasks), noErrors);

  size_t OpIdx = 0;
  std::optional<size_t> DetachOpIdx;
  std::optional<size_t> ShutdownOpIdx;
  S.createService<MockService>(DetachOpIdx, ShutdownOpIdx, OpIdx);

  ASSERT_FALSE(DetachOpIdx);
  ASSERT_FALSE(ShutdownOpIdx);

  // Take a managed code call token. This should succeed.
  auto Tok = TaskGroup::Token(S.managedCodeTokenSource());
  ASSERT_TRUE(Tok);

  // We expect shutdown to wait for any active managed calls to complete.
  bool ShutdownComplete = false;
  S.shutdown([&]() { ShutdownComplete = true; });

  // Detach should have happened, but shutdown should be waiting on token.
  EXPECT_EQ(DetachOpIdx, 0U);
  EXPECT_FALSE(ShutdownOpIdx);
  EXPECT_FALSE(ShutdownComplete);

  // The managed calls code group should have been closed. Assert that we
  // can't get a new token.
  ASSERT_FALSE(TaskGroup::Token(S.managedCodeTokenSource()));

  Tok = TaskGroup::Token(); // Reset token.

  EXPECT_EQ(ShutdownOpIdx, 1U);

  EXPECT_TRUE(ShutdownComplete);
}

static void managedVoidFunction(int *P) { *P = 42; }

TEST(SessionTest, CallManagedCodeVoidFn) {
  // Test calls to a void function while holding a ManagedCodeTaskGroup token.
  Session S(mockExecutorProcessInfo(), noDispatch, noErrors);

  {
    // Pre-shutdown we expect token acquisition to succeed and the function to
    // run.
    int X = 0;
    bool CallSucceeded = S.callManagedCode(managedVoidFunction, &X);

    EXPECT_TRUE(CallSucceeded);
    EXPECT_EQ(X, 42U);
  }

  waitForShutdown(S);

  {
    // Post-shutdown we expect token acquisition to fail, and
    // callManagedCode to return false.
    int X = 0;
    bool CallSucceeded = S.callManagedCode(managedVoidFunction, &X);

    EXPECT_FALSE(CallSucceeded);
  }
}

static int managedNonVoidFunction(int N) { return N + 1; }

TEST(SessionTest, CallManagedCodeNonVoidFn) {
  // Test calls to a non-void function while holding a ManagedCodeTaskGroup
  // token.
  Session S(mockExecutorProcessInfo(), noDispatch, noErrors);

  {
    // Pre-shutdown we expect token acquisition to succeed, the function to be
    // run, and the result to be returned.
    auto Result = S.callManagedCode(managedNonVoidFunction, 41);

    EXPECT_TRUE(Result);
    EXPECT_EQ(*Result, 42U);
  }

  waitForShutdown(S);

  {
    // Post-shutdown we expect token acquisition to fail, and
    // callManagedCode to return std::nullopt.
    auto Result = S.callManagedCode(managedNonVoidFunction, 41);

    EXPECT_EQ(Result, std::nullopt);
  }
}

static void managedAsyncFunction(move_only_function<void(int)> Return, int *P) {
  Return(++*P);
}

TEST(SessionTest, CallManagedCodeAsyncFn) {
  // Test that calls to managed async functions via callManagedCode work.
  Session S(mockExecutorProcessInfo(), noDispatch, noErrors);

  {
    // Pre-shutdown we expect token acquisition to succeed, and the function
    // and Return callback to be run.
    int N = 41;
    std::optional<int> Result;
    S.callManagedCode(managedAsyncFunction, [&](int N) { Result = N; }, &N);
    EXPECT_TRUE(Result);
    EXPECT_EQ(*Result, 42U);
    EXPECT_EQ(N, 42U);
  }

  waitForShutdown(S);

  {
    // Post-shutdown we expect token acquisition to fail. Return should be
    // with `std::nullopt` and the function should not be called.
    int N = 41;
    std::optional<int> Result;
    S.callManagedCode(managedAsyncFunction, [&](int N) { Result = N; }, &N);
    EXPECT_EQ(Result, std::nullopt);
    EXPECT_EQ(N, 41U);
  }
}

TEST(SessionTest, AddServiceAndUseRef) {
  Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
  auto &CS = S.addService(std::make_unique<ConfigurableService>(42));
  CS.doMoreConfig(1);
}

TEST(SessionTest, CreateServiceAndUseRef) {
  Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
  auto &CS = S.createService<ConfigurableService>(42);
  CS.doMoreConfig(1);
}

TEST(SessionTest, TryCreateServiceSuccess) {
  Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
  auto CS = S.tryCreateService<ConfigurableService>(false);
  if (auto Err = CS.takeError()) {
    ADD_FAILURE() << "expected service creation to succeed";
    consumeError(std::move(Err));
  }
}

TEST(SessionTest, TryCreateServiceFailure) {
  Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
  auto CS = S.tryCreateService<ConfigurableService>(true);
  if (auto Err = CS.takeError())
    consumeError(std::move(Err));
  else
    ADD_FAILURE() << "expected service creation to fail";
}

TEST(ControllerAccessTest, Basics) {
  // Test that we can set the ControllerAccess implementation and still shut
  // down as expected.
  QueueingRunner<>::WorkQueue Tasks;
  Session S(mockExecutorProcessInfo(), QueueingRunner(Tasks), noErrors);
  S.attach<MockControllerAccess>(BootstrapInfo(S), postOnto(Tasks));

  QueueingRunner<>::runFIFOUntilEmpty(Tasks);
}

// A ControllerAccess that is attached but whose controller connection is
// already gone, so every callController fails synchronously. Used to exercise
// the failControllerCallInline path in isolation.
class DeadControllerAccess : public Session::ControllerAccess {
public:
  DeadControllerAccess(Session &S) : ControllerAccess(S) {}
  void connect(BootstrapInfo) override {}
  void disconnect() override { notifyDisconnected(); }
  void callController(OnControllerCallReturn OnComplete,
                      orc_rt_ControllerHandlerTag,
                      WrapperFunctionBuffer) override {
    failControllerCallInline(std::move(OnComplete));
  }
  void sendWrapperResult(WrapperFunctionBuffer, uint64_t) override {}
};

TEST(ControllerAccessTest, SynchronousCallControllerFailureRunsInline) {
  // A controller call that fails synchronously (connection already gone) must
  // complete its handler inline -- on the calling thread, before callController
  // returns, and WITHOUT going through Dispatch -- with the canonical
  // "disconnected" out-of-band error. noDispatch ADD_FAILUREs if anything is
  // dispatched, so it doubles as the "ran inline, not via the task queue"
  // check.
  Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
  S.attach<DeadControllerAccess>(BootstrapInfo(S));

  bool HandlerRan = false;
  std::string ErrMsg;
  S.callController(
      [&](WrapperFunctionBuffer Result) {
        HandlerRan = true;
        if (const char *E = Result.getOutOfBandError())
          ErrMsg = E;
      },
      /*T=*/nullptr, WrapperFunctionBuffer());

  // Set synchronously, during the call above -> the handler ran inline.
  EXPECT_TRUE(HandlerRan);
  EXPECT_EQ(ErrMsg, "disconnected");
}

static void add_sps_wrapper(orc_rt_SessionRef S,
                            orc_rt_WrapperFunctionBuffer ArgBytes,
                            orc_rt_WrapperFunctionReturn Return,
                            uint64_t CallId) {
  SPSWrapperFunction<int32_t(int32_t, int32_t)>::handle(
      S, ArgBytes, Return, CallId,
      [](move_only_function<void(int32_t)> Return, int32_t X, int32_t Y) {
        Return(X + Y);
      });
}

// Wrapper handler that echoes its argument bytes straight back as the result.
// Used to exercise the C callController entry point without pulling in SPS
// (de)serialization -- the payload is opaque to the code under test.
static void echo_wrapper(orc_rt_SessionRef S,
                         orc_rt_WrapperFunctionBuffer ArgBytes,
                         orc_rt_WrapperFunctionReturn Return, uint64_t CallId) {
  Return(S, ArgBytes, CallId);
}

// Captures what orc_rt_Session_callController threads back to its C return
// function, so the test can inspect it after the call completes.
struct CAPICallControllerResult {
  bool Ran = false;
  orc_rt_SessionRef S = nullptr;
  std::string Result;
};

static void capiCallControllerReturn(orc_rt_SessionRef S,
                                     orc_rt_WrapperFunctionBuffer ResultBytes,
                                     void *Ctx) {
  auto &R = *static_cast<CAPICallControllerResult *>(Ctx);
  R.Ran = true;
  R.S = S;
  WrapperFunctionBuffer Result(ResultBytes);
  R.Result.assign(Result.data(), Result.size());
}

TEST(ControllerAccessTest, CAPICallControllerRoundTrip) {
  // Drive a controller call through the C API entry point
  // (orc_rt_Session_callController) and confirm that the result bytes, the
  // session handle, and the caller-supplied context are all threaded back to
  // the C return function.
  QueueingRunner<>::WorkQueue Tasks;
  Session S(mockExecutorProcessInfo(), QueueingRunner(Tasks), noErrors);
  S.attach<MockControllerAccess>(BootstrapInfo(S), postOnto(Tasks));

  CAPICallControllerResult R;
  orc_rt_Session_callController(
      wrap(&S), reinterpret_cast<orc_rt_ControllerHandlerTag>(&echo_wrapper),
      WrapperFunctionBuffer::copyFrom("hello", 5).release(),
      &capiCallControllerReturn, &R);

  QueueingRunner<>::runFIFOUntilEmpty(Tasks);

  EXPECT_TRUE(R.Ran) << "C return function never fired";
  EXPECT_EQ(R.S, wrap(&S)) << "Session handle not threaded through";
  EXPECT_EQ(R.Result, "hello") << "Result bytes not round-tripped";
}

TEST(ControllerAccessTest, ValidCallToController) {
  // Simulate a call to a controller handler.
  QueueingRunner<>::WorkQueue Tasks;
  Session S(mockExecutorProcessInfo(), QueueingRunner(Tasks), noErrors);
  S.attach<MockControllerAccess>(BootstrapInfo(S), postOnto(Tasks));

  int32_t Result = 0;
  SPSWrapperFunction<int32_t(int32_t, int32_t)>::call(
      S.controllerCaller(
          reinterpret_cast<orc_rt_ControllerHandlerTag>(add_sps_wrapper)),
      [&](Expected<int32_t> R) { Result = cantFail(std::move(R)); }, 41, 1);

  QueueingRunner<>::runFIFOUntilEmpty(Tasks);

  EXPECT_EQ(Result, 42);
}

TEST(ControllerAccessTest, CallToControllerBeforeAttach) {
  // Expect calls to the controller prior to attaching to fail.
  QueueingRunner<>::WorkQueue Tasks;
  Session S(mockExecutorProcessInfo(), QueueingRunner(Tasks), noErrors);

  Error Err = Error::success();
  SPSWrapperFunction<int32_t(int32_t, int32_t)>::call(
      S.controllerCaller(
          reinterpret_cast<orc_rt_ControllerHandlerTag>(add_sps_wrapper)),
      [&](Expected<int32_t> R) {
        ErrorAsOutParameter _(Err);
        Err = R.takeError();
      },
      41, 1);

  EXPECT_EQ(toString(std::move(Err)), "no controller attached");
}

TEST(ControllerAccessTest, CallToControllerAfterDetach) {
  // Expect calls to the controller prior to attaching to fail.
  QueueingRunner<>::WorkQueue Tasks;
  Session S(mockExecutorProcessInfo(), QueueingRunner(Tasks), noErrors);
  S.attach<MockControllerAccess>(BootstrapInfo(S), postOnto(Tasks));

  S.detach();

  Error Err = Error::success();
  SPSWrapperFunction<int32_t(int32_t, int32_t)>::call(
      S.controllerCaller(
          reinterpret_cast<orc_rt_ControllerHandlerTag>(add_sps_wrapper)),
      [&](Expected<int32_t> R) {
        ErrorAsOutParameter _(Err);
        Err = R.takeError();
      },
      41, 1);

  EXPECT_EQ(toString(std::move(Err)), "no controller attached");
}

TEST(ControllerAccessTest, CallFromController) {
  // Simulate a call from the controller.
  QueueingRunner<>::WorkQueue Tasks;
  Session S(mockExecutorProcessInfo(), QueueingRunner(Tasks), noErrors);
  MockControllerAccess *CA = nullptr;
  S.attach<MockControllerAccess>(BootstrapInfo(S), postOnto(Tasks),
                                 MockControllerAccess::OnConnectFn{}, &CA);

  int32_t Result = 0;
  SPSWrapperFunction<int32_t(int32_t, int32_t)>::call(
      CallFromController(*CA, add_sps_wrapper),
      [&](Expected<int32_t> R) { Result = cantFail(std::move(R)); }, 41, 1);

  QueueingRunner<>::runFIFOUntilEmpty(Tasks);

  EXPECT_EQ(Result, 42);
}

// Stashes Return, via the address passed as the wrapper call's argument,
// instead of calling it -- simulating a wrapper function that defers
// completion past its own return.
static void deferred_wrapper(orc_rt_SessionRef S,
                             orc_rt_WrapperFunctionBuffer ArgBytes,
                             orc_rt_WrapperFunctionReturn Return,
                             uint64_t CallId) {
  SPSWrapperFunction<void(SPSExecutorAddr)>::handle(
      S, ArgBytes, Return, CallId,
      [](move_only_function<void()> Return, ExecutorAddr P) {
        *P.toPtr<move_only_function<void()> *>() = std::move(Return);
      });
}

TEST(ControllerAccessTest, WrapperCallTokenReleasedWhenFnReturns) {
  // A managed-code token acquired for an incoming wrapper call must bracket
  // only the (synchronous) span of Fn's execution -- not the whole
  // call/response chain -- per the "Managed code execution and shutdown"
  // policy in docs/Design.md. Check this by having Fn defer its Return call
  // past its own return, then confirming that Session shutdown's drain phase
  // does not wait on that deferred call.
  QueueingRunner<>::WorkQueue Tasks;
  Session S(mockExecutorProcessInfo(), QueueingRunner(Tasks), noErrors);
  MockControllerAccess *CA = nullptr;
  S.attach<MockControllerAccess>(BootstrapInfo(S), postOnto(Tasks),
                                 MockControllerAccess::OnConnectFn{}, &CA);

  move_only_function<void()> DeferredReturn;

  bool GotResult = false;
  SPSWrapperFunction<void(SPSExecutorAddr)>::call(
      CallFromController(*CA, deferred_wrapper),
      [&](Error Err) {
        cantFail(std::move(Err));
        GotResult = true;
      },
      &DeferredReturn);

  QueueingRunner<>::runFIFOUntilEmpty(Tasks);

  // Fn ran and deferred its Return call, so no result should have been sent
  // back yet.
  ASSERT_TRUE(DeferredReturn);
  EXPECT_FALSE(GotResult);

  // Fn has already returned, so its managed-code token should have been
  // released even though the call is still logically outstanding. Shutdown's
  // drain phase should therefore complete without waiting on the deferred
  // Return call.
  bool ShutdownComplete = false;
  S.shutdown([&] { ShutdownComplete = true; });
  EXPECT_TRUE(ShutdownComplete);
}

TEST(ControllerAccessTest, FailConnect) {
  // Simulate failure to connect.
  bool GotError = false;
  std::string ErrMsg = "failed to connect";
  Session S(mockExecutorProcessInfo(), noDispatch, [&](Error Err) {
    GotError = true;
    EXPECT_EQ(toString(std::move(Err)), ErrMsg);
  });
  BootstrapInfo BI(S);
  S.attach<MockControllerAccess>(
      std::move(BI), MockControllerAccess::PostFn{},
      [&](BootstrapInfo &BI) { return make_error<StringError>(ErrMsg); });
  ASSERT_TRUE(GotError);
}

TEST(ControllerAccessTest, BootstrapInfoPassedToConnect) {
  Session S(mockExecutorProcessInfo(), noDispatch, noErrors);

  // Test values.
  constexpr const char *SymName = "test_sym";
  const char Sym = '.';
  constexpr const char *SecretKey = "luggage_combo";
  constexpr const char *SecretValue = "12345";

  // Build a BootstrapInfo with custom symbols and values.
  BootstrapInfo BI(S);
  std::pair<const char *, const void *> TestSyms[] = {
      {SymName, static_cast<const void *>(&Sym)}};
  cantFail(BI.symbols().addUnique(TestSyms));
  BI.values()[SecretKey] = SecretValue;

  bool OnConnectRan = false;
  S.attach<MockControllerAccess>(
      std::move(BI), MockControllerAccess::PostFn{}, [&](BootstrapInfo &BI) {
        EXPECT_EQ(BI.symbols().at(SymName), static_cast<const void *>(&Sym));
        EXPECT_EQ(BI.values().at(SecretKey), SecretValue);
        OnConnectRan = true;
        return Error::success();
      });

  ASSERT_TRUE(OnConnectRan);
}

TEST(ControllerAccessTest, TryAttachSuccess) {
  // A successful Create attaches the controller, which then services calls
  // just like one attached via attach<T>.
  QueueingRunner<>::WorkQueue Tasks;
  Session S(mockExecutorProcessInfo(), QueueingRunner(Tasks), noErrors);
  cantFail(S.tryAttach<MockControllerAccess>(BootstrapInfo(S), /*Fail=*/false,
                                             postOnto(Tasks)));

  int32_t Result = 0;
  SPSWrapperFunction<int32_t(int32_t, int32_t)>::call(
      S.controllerCaller(
          reinterpret_cast<orc_rt_ControllerHandlerTag>(add_sps_wrapper)),
      [&](Expected<int32_t> R) { Result = cantFail(std::move(R)); }, 41, 1);

  QueueingRunner<>::runFIFOUntilEmpty(Tasks);

  EXPECT_EQ(Result, 42);
}

TEST(ControllerAccessTest, TryAttachFailure) {
  // A failing Create surfaces its Error and leaves the Session unattached.
  Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
  auto Err = S.tryAttach<MockControllerAccess>(BootstrapInfo(S), /*Fail=*/true);
  ASSERT_TRUE(static_cast<bool>(Err));
  EXPECT_EQ(toString(std::move(Err)), "failed to create controller access");

  // Since nothing was attached, calls to the controller should fail as they
  // would before any attach.
  Error CallErr = Error::success();
  SPSWrapperFunction<int32_t(int32_t, int32_t)>::call(
      S.controllerCaller(
          reinterpret_cast<orc_rt_ControllerHandlerTag>(add_sps_wrapper)),
      [&](Expected<int32_t> R) {
        ErrorAsOutParameter _(CallErr);
        CallErr = R.takeError();
      },
      41, 1);

  EXPECT_EQ(toString(std::move(CallErr)), "no controller attached");
}
