//===- Session.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
//
//===----------------------------------------------------------------------===//
//
// Contains the implementation of the Session class and related APIs.
//
//===----------------------------------------------------------------------===//

#include "orc-rt/Session.h"

namespace orc_rt {

Session::ControllerAccess::~ControllerAccess() = default;

Session::~Session() { waitForShutdown(); }

void Session::shutdown(OnShutdownCompleteFn OnShutdownComplete) {
  // Safe to call concurrently / redundantly.
  detachFromController();

  {
    std::scoped_lock<std::mutex> Lock(M);
    if (SI) {
      SI->OnCompletes.push_back(std::move(OnShutdownComplete));
      return;
    }

    SI = std::make_unique<ShutdownInfo>();
    SI->OnCompletes.push_back(std::move(OnShutdownComplete));
    std::swap(SI->ResourceMgrs, ResourceMgrs);
  }

  shutdownNext(Error::success());
}

void Session::waitForShutdown() {
  shutdown([]() {});
  std::unique_lock<std::mutex> Lock(M);
  SI->CompleteCV.wait(Lock, [&]() { return SI->Complete; });
}

void Session::addResourceManager(std::unique_ptr<ResourceManager> RM) {
  std::scoped_lock<std::mutex> Lock(M);
  assert(!SI && "addResourceManager called after shutdown");
  ResourceMgrs.push_back(std::move(RM));
}

void Session::setController(std::shared_ptr<ControllerAccess> CA) {
  assert(CA && "Cannot attach null controller");
  std::scoped_lock<std::mutex> Lock(M);
  assert(!this->CA && "Cannot re-attach controller");
  assert(!SI && "Cannot attach controller after shutdown");
  this->CA = std::move(CA);
}

void Session::detachFromController() {
  if (auto TmpCA = CA) {
    TmpCA->doDisconnect();
    CA = nullptr;
  }
}

void Session::shutdownNext(Error Err) {
  if (Err)
    reportError(std::move(Err));

  if (SI->ResourceMgrs.empty())
    return shutdownComplete();

  // Get the next ResourceManager to shut down.
  auto NextRM = std::move(SI->ResourceMgrs.back());
  SI->ResourceMgrs.pop_back();
  NextRM->shutdown([this](Error Err) { shutdownNext(std::move(Err)); });
}

void Session::shutdownComplete() {

  std::unique_ptr<TaskDispatcher> TmpDispatcher;
  {
    std::lock_guard<std::mutex> Lock(M);
    TmpDispatcher = std::move(Dispatcher);
  }

  TmpDispatcher->shutdown();

  for (auto &OnShutdownComplete : SI->OnCompletes)
    OnShutdownComplete();

  {
    std::lock_guard<std::mutex> Lock(M);
    SI->Complete = true;
  }

  SI->CompleteCV.notify_all();
}

void Session::wrapperReturn(orc_rt_SessionRef S, uint64_t CallId,
                            orc_rt_WrapperFunctionBuffer ResultBytes) {
  unwrap(S)->sendWrapperResult(CallId, ResultBytes);
}

} // namespace orc_rt
