//===- LibraryResolver.cpp - Library Resolution of Unresolved Symbols ---===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Library resolution impl for unresolved symbols
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h"

#include "llvm/ADT/StringSet.h"

#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"

#include <mutex>
#include <thread>

#define DEBUG_TYPE "orc-resolver"

namespace llvm::orc {

LibraryResolver::LibraryResolver(const LibraryResolver::Setup &S)
    : LibPathCache(S.Cache ? S.Cache : std::make_shared<LibraryPathCache>()),
      LibPathResolver(S.PResolver
                          ? S.PResolver
                          : std::make_shared<PathResolver>(LibPathCache)),
      ScanHelper(S.BasePaths, LibPathCache, LibPathResolver),
      FB(S.FilterBuilder), LibMgr(),
      ShouldScanCall(S.ShouldScanCall ? S.ShouldScanCall
                                      : [](StringRef) -> bool { return true; }),
      scanBatchSize(S.ScanBatchSize) {

  if (ScanHelper.getAllUnits().empty()) {
    LLVM_DEBUG(dbgs() << "Warning: No base paths provided for scanning.\n");
  }
}

std::unique_ptr<LibraryResolutionDriver>
LibraryResolutionDriver::create(const LibraryResolver::Setup &S) {
  auto LR = std::make_unique<LibraryResolver>(S);
  return std::unique_ptr<LibraryResolutionDriver>(
      new LibraryResolutionDriver(std::move(LR)));
}

void LibraryResolutionDriver::addScanPath(const std::string &Path, PathType K) {
  LR->ScanHelper.addBasePath(Path, K);
}

bool LibraryResolutionDriver::markLibraryLoaded(StringRef Path) {
  auto Lib = LR->LibMgr.getLibrary(Path);
  if (!Lib)
    return false;

  Lib->setState(LibraryManager::LibState::Loaded);

  return true;
}

bool LibraryResolutionDriver::markLibraryUnLoaded(StringRef Path) {
  auto Lib = LR->LibMgr.getLibrary(Path);
  if (!Lib)
    return false;

  Lib->setState(LibraryManager::LibState::Unloaded);

  return true;
}

void LibraryResolutionDriver::resolveSymbols(
    std::vector<std::string> Syms,
    LibraryResolver::OnSearchComplete OnCompletion,
    const SearchConfig &Config) {
  LR->searchSymbolsInLibraries(Syms, std::move(OnCompletion), Config);
}

static bool shouldIgnoreSymbol(const object::SymbolRef &Sym,
                               uint32_t IgnoreFlags) {
  Expected<uint32_t> FlagsOrErr = Sym.getFlags();
  if (!FlagsOrErr) {
    consumeError(FlagsOrErr.takeError());
    return true;
  }

  uint32_t Flags = *FlagsOrErr;

  using Filter = SymbolEnumeratorOptions;
  if ((IgnoreFlags & Filter::IgnoreUndefined) &&
      (Flags & object::SymbolRef::SF_Undefined))
    return true;
  if ((IgnoreFlags & Filter::IgnoreIndirect) &&
      (Flags & object::SymbolRef::SF_Indirect))
    return true;
  if ((IgnoreFlags & Filter::IgnoreWeak) &&
      (Flags & object::SymbolRef::SF_Weak))
    return true;

  return false;
}

bool SymbolEnumerator::enumerateSymbols(StringRef Path, OnEachSymbolFn OnEach,
                                        const SymbolEnumeratorOptions &Opts) {
  if (Path.empty())
    return false;

  ObjectFileLoader ObjLoader(Path);

  auto ObjOrErr = ObjLoader.getObjectFile();
  if (!ObjOrErr) {
    std::string ErrMsg;
    handleAllErrors(ObjOrErr.takeError(),
                    [&](const ErrorInfoBase &EIB) { ErrMsg = EIB.message(); });
    LLVM_DEBUG(dbgs() << "Failed loading object file: " << Path
                      << "\nError: " << ErrMsg << "\n");
    return false;
  }

  object::ObjectFile *Obj = &ObjOrErr.get();

  auto processSymbolRange =
      [&](object::ObjectFile::symbol_iterator_range Range) -> EnumerateResult {
    for (const auto &Sym : Range) {
      if (shouldIgnoreSymbol(Sym, Opts.FilterFlags))
        continue;

      auto NameOrErr = Sym.getName();
      if (!NameOrErr) {
        consumeError(NameOrErr.takeError());
        continue;
      }

      StringRef Name = *NameOrErr;
      if (Name.empty())
        continue;

      EnumerateResult Res = OnEach(Name);
      if (Res != EnumerateResult::Continue)
        return Res;
    }
    return EnumerateResult::Continue;
  };

  EnumerateResult Res = processSymbolRange(Obj->symbols());
  if (Res != EnumerateResult::Continue)
    return Res == EnumerateResult::Stop;

  if (Obj->isELF()) {
    const auto *ElfObj = cast<object::ELFObjectFileBase>(Obj);
    Res = processSymbolRange(ElfObj->getDynamicSymbolIterators());
    if (Res != EnumerateResult::Continue)
      return Res == EnumerateResult::Stop;
  } else if (Obj->isCOFF()) {
    const auto *CoffObj = cast<object::COFFObjectFile>(Obj);
    for (auto I = CoffObj->export_directory_begin(),
              E = CoffObj->export_directory_end();
         I != E; ++I) {
      StringRef Name;
      if (I->getSymbolName(Name))
        continue;
      if (Name.empty())
        continue;

      EnumerateResult Res = OnEach(Name);
      if (Res != EnumerateResult::Continue)
        return Res == EnumerateResult::Stop;
    }
  } else if (Obj->isMachO()) {
  }

  return true;
}

class SymbolSearchContext {
public:
  SymbolSearchContext(SymbolQuery &Q) : Q(Q) {}

  bool hasSearched(const LibraryInfo *Lib) const { return Searched.count(Lib); }

  void markSearched(const LibraryInfo *Lib) { Searched.insert(Lib); }

  inline bool allResolved() const { return Q.allResolved(); }

  SymbolQuery &query() { return Q; }

private:
  SymbolQuery &Q;
  DenseSet<const LibraryInfo *> Searched;
};

void LibraryResolver::resolveSymbolsInLibrary(
    LibraryInfo &Lib, SymbolQuery &UnresolvedSymbols,
    const SymbolEnumeratorOptions &Opts) {
  LLVM_DEBUG(dbgs() << "Checking unresolved symbols "
                    << " in library : " << Lib.getFileName() << "\n";);
  StringSet<> DiscoveredSymbols;

  if (!UnresolvedSymbols.hasUnresolved()) {
    LLVM_DEBUG(dbgs() << "Skipping library: " << Lib.getFullPath()
                      << " — unresolved symbols exist.\n";);
    return;
  }

  bool HasEnumerated = false;
  auto enumerateSymbolsIfNeeded = [&]() {
    if (HasEnumerated)
      return;

    HasEnumerated = true;

    LLVM_DEBUG(dbgs() << "Enumerating symbols in library: " << Lib.getFullPath()
                      << "\n";);
    SymbolEnumerator::enumerateSymbols(
        Lib.getFullPath(),
        [&](StringRef sym) {
          DiscoveredSymbols.insert(sym);
          return EnumerateResult::Continue;
        },
        Opts);
  };

  if (!Lib.hasFilter()) {
    LLVM_DEBUG(dbgs() << "Building filter for library: " << Lib.getFullPath()
                      << "\n";);
    enumerateSymbolsIfNeeded();
    if (DiscoveredSymbols.empty()) {
      LLVM_DEBUG(dbgs() << "  No symbols and remove library : "
                        << Lib.getFullPath() << "\n";);
      LibMgr.removeLibrary(Lib.getFullPath());
      return;
    }
    SmallVector<StringRef> SymbolVec;
    SymbolVec.reserve(DiscoveredSymbols.size());
    for (const auto &KV : DiscoveredSymbols)
      SymbolVec.push_back(KV.first());

    Lib.ensureFilterBuilt(FB, SymbolVec);
    LLVM_DEBUG({
      dbgs() << "DiscoveredSymbols : " << DiscoveredSymbols.size() << "\n";
      for (const auto &KV : DiscoveredSymbols)
        dbgs() << "DiscoveredSymbols : " << KV.first() << "\n";
    });
  }

  const auto &Unresolved = UnresolvedSymbols.getUnresolvedSymbols();
  bool HadAnySym = false;
  LLVM_DEBUG(dbgs() << "Total unresolved symbols : " << Unresolved.size()
                    << "\n";);
  for (const auto &Sym : Unresolved) {
    if (Lib.mayContain(Sym)) {
      LLVM_DEBUG(dbgs() << "Checking symbol '" << Sym
                        << "' in library: " << Lib.getFullPath() << "\n";);
      enumerateSymbolsIfNeeded();
      if (DiscoveredSymbols.count(Sym) > 0) {
        LLVM_DEBUG(dbgs() << "  Resolved symbol: " << Sym
                          << " in library: " << Lib.getFullPath() << "\n";);
        UnresolvedSymbols.resolve(Sym, Lib.getFullPath());
        HadAnySym = true;
      }
    }
  }

  using LibraryState = LibraryManager::LibState;
  if (HadAnySym && Lib.getState() != LibraryState::Loaded)
    Lib.setState(LibraryState::Queried);
}

void LibraryResolver::searchSymbolsInLibraries(
    std::vector<std::string> &SymbolList, OnSearchComplete OnComplete,
    const SearchConfig &Config) {
  SymbolQuery Q(SymbolList);

  using LibraryState = LibraryManager::LibState;
  using LibraryType = PathType;
  auto tryResolveFrom = [&](LibraryState S, LibraryType K) {
    LLVM_DEBUG(dbgs() << "Trying resolve from state=" << static_cast<int>(S)
                      << " type=" << static_cast<int>(K) << "\n";);

    SymbolSearchContext Ctx(Q);
    while (!Ctx.allResolved()) {
      std::vector<std::shared_ptr<LibraryInfo>> Libs;
      LibMgr.getLibraries(S, K, Libs, [&](const LibraryInfo &Lib) {
        return !Ctx.hasSearched(&Lib);
      });

      if (Libs.empty() && !scanLibrariesIfNeeded(K, scanBatchSize))
        break; // no more new libs to scan

      for (auto &Lib : Libs) {
        // can use Async here?
        resolveSymbolsInLibrary(*Lib, Ctx.query(), Config.Options);
        Ctx.markSearched(Lib.get());

        if (Ctx.allResolved())
          return;
      }
    }
  };

  for (const auto &[St, Ty] : Config.Policy.Plan) {
    tryResolveFrom(St, Ty);
    if (Q.allResolved())
      break;
  }

  // done:
  LLVM_DEBUG({
    dbgs() << "Search complete.\n";
    for (const auto &r : Q.getAllResults())
      dbgs() << "Resolved Symbol:" << r->Name << " -> " << r->ResolvedLibPath
             << "\n";
  });

  OnComplete(Q);
}

bool LibraryResolver::scanLibrariesIfNeeded(PathType PK, size_t BatchSize) {
  LLVM_DEBUG(dbgs() << "LibraryResolver::scanLibrariesIfNeeded: Scanning for "
                    << (PK == PathType::User ? "User" : "System")
                    << " libraries\n";);
  if (!ScanHelper.leftToScan(PK))
    return false;

  LibraryScanner Scanner(ScanHelper, LibMgr, ShouldScanCall);
  Scanner.scanNext(PK, BatchSize);
  return true;
}

bool LibraryResolver::symbolExistsInLibrary(const LibraryInfo &Lib,
                                            StringRef SymName,
                                            std::vector<std::string> *AllSyms) {
  SymbolEnumeratorOptions Opts;
  return symbolExistsInLibrary(Lib, SymName, AllSyms, Opts);
}

bool LibraryResolver::symbolExistsInLibrary(
    const LibraryInfo &Lib, StringRef SymName,
    std::vector<std::string> *AllSyms, const SymbolEnumeratorOptions &Opts) {
  bool Found = false;

  SymbolEnumerator::enumerateSymbols(
      Lib.getFullPath(),
      [&](StringRef Sym) {
        if (AllSyms)
          AllSyms->emplace_back(Sym.str());

        if (Sym == SymName) {
          Found = true;
        }

        return EnumerateResult::Continue;
      },
      Opts);

  return Found;
}

} // end namespace llvm::orc
