//===- LookupAndApply.cpp - Compose a lookup from handlers ----------------===//
//
// 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/LookupAndApply.h"

#include "llvm/Support/MSVCErrorWorkarounds.h"

#include <future>

namespace llvm::orc {

void lookupAndApply(unique_function<void(Error)> OnApplied, LookupKind K,
                    const JITDylibSearchOrder &SearchOrder,
                    ArrayRef<LookupPrepareFn> PrepareFns) {

  /// Empty PrepareFns list trivially succeeds.
  if (PrepareFns.empty())
    return OnApplied(Error::success());

  /// Otherwise an empty SearchOrder trivially fails: Without it we don't have
  /// the ExecutionSession that we need to pass into the prepare functions.
  if (SearchOrder.empty())
    return OnApplied(
        make_error<StringError>("lookupAndApply failed: search order is empty",
                                inconvertibleErrorCode()));

  auto &ES = SearchOrder.front().first->getExecutionSession();

  // Collect the symbols to look up. Each prepare function hands back the
  // applicator that will act on the result; the prepare functions themselves
  // are not needed beyond this point.
  SymbolLookupSet Symbols;
  std::vector<LookupApplyFn> Applies;
  Applies.reserve(PrepareFns.size());
  for (const auto &PF : PrepareFns)
    Applies.push_back(PF(Symbols, ES));

  // PrepareFns are independent, so two of them may legitimately ask for the
  // same symbol. ExecutionSession::lookup requires a duplicate-free set, and
  // the applicators read the result by name, so merging here is invisible to
  // them.
  Symbols.mergeEntries();

  ES.lookup(
      K, SearchOrder, std::move(Symbols), SymbolState::Ready,
      [Applies = std::move(Applies),
       OnApplied = std::move(OnApplied)](Expected<SymbolMap> Result) mutable {
        if (!Result)
          return OnApplied(Result.takeError());
        for (auto &Apply : Applies)
          Apply(*Result);
        OnApplied(Error::success());
      },
      NoDependenciesToRegister);
}

Error lookupAndApply(LookupKind K, const JITDylibSearchOrder &SearchOrder,
                     ArrayRef<LookupPrepareFn> PrepareFns) {
  std::promise<MSVCPError> ResultP;
  auto ResultF = ResultP.get_future();
  lookupAndApply([&](Error Err) { ResultP.set_value(std::move(Err)); }, K,
                 SearchOrder, PrepareFns);
  return ResultF.get();
}

void lookupAndApply(unique_function<void(Error)> OnApplied, JITDylib &JD,
                    ArrayRef<LookupPrepareFn> PrepareFns) {
  lookupAndApply(std::move(OnApplied), LookupKind::Static,
                 makeJITDylibSearchOrder(&JD), PrepareFns);
}

Error lookupAndApply(JITDylib &JD, ArrayRef<LookupPrepareFn> PrepareFns) {
  return lookupAndApply(LookupKind::Static, makeJITDylibSearchOrder(&JD),
                        PrepareFns);
}

} // namespace llvm::orc
