//===- LibraryScanner.cpp - Provide Library Scanning Implementation ----===//
//
// 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/TargetProcess/LibraryScanner.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h"

#include "llvm/ADT/StringExtras.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/ELFTypes.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/TargetParser/Host.h"
#include "llvm/TargetParser/Triple.h"

#ifdef LLVM_ON_UNIX
#include <sys/stat.h>
#include <unistd.h>
#endif // LLVM_ON_UNIX

#ifdef __APPLE__
#include <sys/stat.h>
#undef LC_LOAD_DYLIB
#undef LC_RPATH
#endif // __APPLE__

#define DEBUG_TYPE "orc-scanner"

namespace llvm::orc {

void handleError(Error Err, StringRef context = "") {
  consumeError(handleErrors(std::move(Err), [&](const ErrorInfoBase &EIB) {
    dbgs() << "LLVM Error";
    if (!context.empty())
      dbgs() << " [" << context << "]";
    dbgs() << ": " << EIB.message() << "\n";
  }));
}

bool ObjectFileLoader::isArchitectureCompatible(const object::ObjectFile &Obj) {
  static const llvm::Triple HostTriple(llvm::sys::getProcessTriple());

  if (HostTriple.getArch() != Obj.getArch())
    return false;

  if (Obj.getTripleObjectFormat() != HostTriple.getObjectFormat())
    return false;

  return true;
}

Expected<object::OwningBinary<object::ObjectFile>>
ObjectFileLoader::loadObjectFileWithOwnership(StringRef FilePath) {
  LLVM_DEBUG(dbgs() << "ObjectFileLoader: Attempting to open file " << FilePath
                    << "\n";);
  if (auto ObjOrErr = object::ObjectFile::createObjectFile(FilePath)) {

    LLVM_DEBUG(dbgs() << "ObjectFileLoader: Detected object file\n";);

    auto OwningBin = std::move(*ObjOrErr);

    if (!isArchitectureCompatible(*OwningBin.getBinary())) {
      LLVM_DEBUG(dbgs() << "ObjectFileLoader: Incompatible architecture: "
                        << FilePath << "\n";);
      return createStringError(inconvertibleErrorCode(),
                               "Incompatible object file: %s",
                               FilePath.str().c_str());
    }

    LLVM_DEBUG(dbgs() << "ObjectFileLoader: Object file is compatible\n";);

    return std::move(OwningBin);
  } else {
#if defined(__APPLE__)
    consumeError(ObjOrErr.takeError());
    auto BinOrErr = object::createBinary(FilePath);
    if (!BinOrErr) {
      LLVM_DEBUG(dbgs() << "ObjectFileLoader: Failed to open file " << FilePath
                        << "\n";);
      return BinOrErr.takeError();
    }

    LLVM_DEBUG(dbgs() << "ObjectFileLoader: Successfully opened file "
                      << FilePath << "\n";);

    auto OwningBin = BinOrErr->takeBinary();
    object::Binary *Bin = OwningBin.first.get();

    if (Bin->isArchive()) {
      LLVM_DEBUG(
          dbgs() << "ObjectFileLoader: File is an archive, not supported: "
                 << FilePath << "\n";);
      return createStringError(std::errc::invalid_argument,
                               "Archive files are not supported: %s",
                               FilePath.str().c_str());
    }

    if (auto *UB = dyn_cast<object::MachOUniversalBinary>(Bin)) {
      LLVM_DEBUG(
          dbgs() << "ObjectFileLoader: Detected Mach-O universal binary: "
                 << FilePath << "\n";);
      for (auto ObjForArch : UB->objects()) {
        auto ObjOrErr = ObjForArch.getAsObjectFile();
        if (!ObjOrErr) {
          LLVM_DEBUG(dbgs() << "ObjectFileLoader: Skipping invalid "
                               "architecture slice\n";);

          consumeError(ObjOrErr.takeError());
          continue;
        }

        std::unique_ptr<object::ObjectFile> Obj = std::move(ObjOrErr.get());
        if (isArchitectureCompatible(*Obj)) {
          LLVM_DEBUG(
              dbgs() << "ObjectFileLoader: Found compatible object slice\n";);

          return object::OwningBinary<object::ObjectFile>(
              std::move(Obj), std::move(OwningBin.second));

        } else {
          LLVM_DEBUG(dbgs() << "ObjectFileLoader: Incompatible architecture "
                               "slice skipped\n";);
        }
      }
      LLVM_DEBUG(dbgs() << "ObjectFileLoader: No compatible slices found in "
                           "universal binary\n";);
      return createStringError(inconvertibleErrorCode(),
                               "No compatible object found in fat binary: %s",
                               FilePath.str().c_str());
    }
    return ObjOrErr.takeError();
#else
    LLVM_DEBUG(dbgs() << "ObjectFileLoader: Failed to open file " << FilePath
                      << "\n";);
    return ObjOrErr.takeError();
#endif
  }

  return createStringError(inconvertibleErrorCode(),
                           "Not a compatible object file : %s",
                           FilePath.str().c_str());
}

template <class ELFT>
bool isELFSharedLibrary(const object::ELFFile<ELFT> &ELFObj) {
  if (ELFObj.getHeader().e_type != ELF::ET_DYN)
    return false;

  auto PHOrErr = ELFObj.program_headers();
  if (!PHOrErr) {
    consumeError(PHOrErr.takeError());
    return true;
  }

  for (auto Phdr : *PHOrErr) {
    if (Phdr.p_type == ELF::PT_INTERP)
      return false;
  }

  return true;
}

bool isSharedLibraryObject(object::ObjectFile &Obj) {
  if (Obj.isELF()) {
    if (auto *ELF32LE = dyn_cast<object::ELF32LEObjectFile>(&Obj))
      return isELFSharedLibrary(ELF32LE->getELFFile());
    if (auto *ELF64LE = dyn_cast<object::ELF64LEObjectFile>(&Obj))
      return isELFSharedLibrary(ELF64LE->getELFFile());
    if (auto *ELF32BE = dyn_cast<object::ELF32BEObjectFile>(&Obj))
      return isELFSharedLibrary(ELF32BE->getELFFile());
    if (auto *ELF64BE = dyn_cast<object::ELF64BEObjectFile>(&Obj))
      return isELFSharedLibrary(ELF64BE->getELFFile());
  } else if (Obj.isMachO()) {
    const object::MachOObjectFile *MachO =
        dyn_cast<object::MachOObjectFile>(&Obj);
    if (!MachO) {
      LLVM_DEBUG(dbgs() << "Failed to cast to MachOObjectFile.\n";);
      return false;
    }
    LLVM_DEBUG({
      bool Result =
          MachO->getHeader().filetype == MachO::HeaderFileType::MH_DYLIB;
      dbgs() << "Mach-O filetype: " << MachO->getHeader().filetype
             << " (MH_DYLIB == " << MachO::HeaderFileType::MH_DYLIB
             << "), shared: " << Result << "\n";
    });

    return MachO->getHeader().filetype == MachO::HeaderFileType::MH_DYLIB;
  } else if (Obj.isCOFF()) {
    const object::COFFObjectFile *coff = dyn_cast<object::COFFObjectFile>(&Obj);
    if (!coff)
      return false;
    return coff->getCharacteristics() & COFF::IMAGE_FILE_DLL;
  } else {
    LLVM_DEBUG(dbgs() << "Binary is not an ObjectFile.\n";);
  }

  return false;
}

bool DylibPathValidator::isSharedLibrary(StringRef Path) const {
  LLVM_DEBUG(dbgs() << "Checking if path is a shared library: " << Path
                    << "\n";);

  auto FileType = sys::fs::get_file_type(Path, /*Follow*/ true);
  if (FileType != sys::fs::file_type::regular_file) {
    LLVM_DEBUG(dbgs() << "File type is not a regular file for path: " << Path
                      << "\n";);
    return false;
  }

  file_magic MagicCode;
  identify_magic(Path, MagicCode);

  // Skip archives.
  if (MagicCode == file_magic::archive)
    return false;

  // Object file inspection for PE/COFF, ELF, and Mach-O
  bool NeedsObjectInspection =
#if defined(_WIN32)
      (MagicCode == file_magic::pecoff_executable);
#elif defined(__APPLE__)
      (MagicCode == file_magic::macho_universal_binary ||
       MagicCode == file_magic::macho_fixed_virtual_memory_shared_lib ||
       MagicCode == file_magic::macho_dynamically_linked_shared_lib ||
       MagicCode == file_magic::macho_dynamically_linked_shared_lib_stub);
#elif defined(LLVM_ON_UNIX)
#ifdef __CYGWIN__
      (MagicCode == file_magic::pecoff_executable);
#else
      (MagicCode == file_magic::elf_shared_object);
#endif
#else
#error "Unsupported platform."
#endif

  if (!NeedsObjectInspection) {
    LLVM_DEBUG(dbgs() << "Path is not identified as a shared library: " << Path
                      << "\n";);
    return false;
  }

  ObjectFileLoader ObjLoader(Path);
  auto ObjOrErr = ObjLoader.getObjectFile();
  if (!ObjOrErr) {
    consumeError(ObjOrErr.takeError());
    return false;
  }

  bool IsShared = isSharedLibraryObject(ObjOrErr.get());

  if (IsShared && ObjCache)
    ObjCache->insert(Path, std::move(ObjLoader));

  return IsShared;
}

void DylibSubstitutor::configure(StringRef LoaderPath) {
  SmallString<512> ExecPath(sys::fs::getMainExecutable(nullptr, nullptr));
  sys::path::remove_filename(ExecPath);

  SmallString<512> LoaderDir;
  if (LoaderPath.empty()) {
    LoaderDir = ExecPath;
  } else {
    LoaderDir = LoaderPath.str();
    if (!sys::fs::is_directory(LoaderPath))
      sys::path::remove_filename(LoaderDir);
  }

#ifdef __APPLE__
  Placeholders.push_back({"@loader_path", std::string(LoaderDir)});
  Placeholders.push_back({"@executable_path", std::string(ExecPath)});
#else
  Placeholders.push_back({"$origin", std::string(LoaderDir)});
#endif
}

std::optional<std::string>
SearchPathResolver::resolve(StringRef Stem, const DylibSubstitutor &Subst,
                            DylibPathValidator &Validator) const {
  for (const auto &SP : Paths) {
    std::string Base = Subst.substitute(SP);

    SmallString<512> FullPath(Base);
    if (!PlaceholderPrefix.empty() &&
        Stem.starts_with_insensitive(PlaceholderPrefix))
      FullPath.append(Stem.drop_front(PlaceholderPrefix.size()));
    else
      sys::path::append(FullPath, Stem);

    LLVM_DEBUG(dbgs() << "SearchPathResolver::resolve FullPath = " << FullPath
                      << "\n";);

    if (auto Valid = Validator.validate(FullPath.str()))
      return Valid;
  }

  return std::nullopt;
}

std::optional<std::string>
DylibResolverImpl::tryWithExtensions(StringRef LibStem) const {
  LLVM_DEBUG(dbgs() << "tryWithExtensions: baseName = " << LibStem << "\n";);
  SmallVector<SmallString<256>, 8> Candidates;

  // Add extensions by platform
#if defined(__APPLE__)
  Candidates.emplace_back(LibStem);
  Candidates.back() += ".dylib";
#elif defined(_WIN32)
  Candidates.emplace_back(LibStem);
  Candidates.back() += ".dll";
#else
  Candidates.emplace_back(LibStem);
  Candidates.back() += ".so";
#endif

  // Optionally try "lib" prefix if not already there
  StringRef FileName = sys::path::filename(LibStem);
  StringRef Base = sys::path::parent_path(LibStem);
  if (!FileName.starts_with("lib")) {
    SmallString<256> WithPrefix(Base);
    if (!WithPrefix.empty())
      sys::path::append(WithPrefix, ""); // ensure separator if needed
    WithPrefix += "lib";
    WithPrefix += FileName;

#if defined(__APPLE__)
    WithPrefix += ".dylib";
#elif defined(_WIN32)
    WithPrefix += ".dll";
#else
    WithPrefix += ".so";
#endif

    Candidates.push_back(std::move(WithPrefix));
  }

  LLVM_DEBUG({
    dbgs() << "  Candidates to try:\n";
    for (const auto &C : Candidates)
      dbgs() << "    " << C << "\n";
  });

  // Try all variants using tryAllPaths
  for (const auto &Name : Candidates) {

    LLVM_DEBUG(dbgs() << "  Trying candidate: " << Name << "\n";);

    for (const auto &R : Resolvers) {
      if (auto Res = R.resolve(Name, Substitutor, Validator))
        return Res;
    }
  }

  LLVM_DEBUG(dbgs() << "  -> No candidate Resolved.\n";);

  return std::nullopt;
}

std::optional<std::string>
DylibResolverImpl::resolve(StringRef LibStem, bool VariateLibStem) const {
  LLVM_DEBUG(dbgs() << "Resolving library stem: " << LibStem << "\n";);

  // If it is an absolute path, don't try iterate over the paths.
  if (sys::path::is_absolute(LibStem)) {
    LLVM_DEBUG(dbgs() << "  -> Absolute path detected.\n";);
    return Validator.validate(LibStem);
  }

  if (!LibStem.starts_with_insensitive("@rpath")) {
    if (auto norm = Validator.validate(Substitutor.substitute(LibStem))) {
      LLVM_DEBUG(dbgs() << "  -> Resolved after substitution: " << *norm
                        << "\n";);

      return norm;
    }
  }

  for (const auto &R : Resolvers) {
    LLVM_DEBUG(dbgs() << "  -> Resolving via search path ... \n";);
    if (auto Result = R.resolve(LibStem, Substitutor, Validator)) {
      LLVM_DEBUG(dbgs() << "  -> Resolved via search path: " << *Result
                        << "\n";);

      return Result;
    }
  }

  // Expand libStem with paths, extensions, etc.
  // std::string foundName;
  if (VariateLibStem) {
    LLVM_DEBUG(dbgs() << "  -> Trying with extensions...\n";);

    if (auto Norm = tryWithExtensions(LibStem)) {
      LLVM_DEBUG(dbgs() << "  -> Resolved via tryWithExtensions: " << *Norm
                        << "\n";);
      return Norm;
    }
  }

  LLVM_DEBUG(dbgs() << "  -> Could not resolve: " << LibStem << "\n";);

  return std::nullopt;
}

#ifndef _WIN32
mode_t PathResolver::lstatCached(StringRef Path) {
  // If already cached - retun cached result
  if (auto Cache = LibPathCache->read_lstat(Path))
    return *Cache;

  // Not cached: perform lstat and store
  struct stat buf{};
  mode_t st_mode = (lstat(Path.str().c_str(), &buf) == -1) ? 0 : buf.st_mode;

  LibPathCache->insert_lstat(Path, st_mode);

  return st_mode;
}

std::optional<std::string> PathResolver::readlinkCached(StringRef Path) {
  // If already cached - retun cached result
  if (auto Cache = LibPathCache->read_link(Path))
    return Cache;

  // If result not in cache - call system function and cache result
  char buf[PATH_MAX];
  ssize_t len;
  if ((len = readlink(Path.str().c_str(), buf, sizeof(buf))) != -1) {
    buf[len] = '\0';
    std::string s(buf);
    LibPathCache->insert_link(Path, s);
    return s;
  }
  return std::nullopt;
}

void createComponent(StringRef Path, StringRef BasePath, bool BaseIsResolved,
                     SmallVector<StringRef, 16> &Component) {
  StringRef Separator = sys::path::get_separator();
  if (!BaseIsResolved) {
    if (Path[0] == '~' &&
        (Path.size() == 1 || sys::path::is_separator(Path[1]))) {
      static SmallString<128> HomeP;
      if (HomeP.str().empty())
        sys::path::home_directory(HomeP);
      StringRef(HomeP).split(Component, Separator, /*MaxSplit*/ -1,
                             /*KeepEmpty*/ false);
    } else if (BasePath.empty()) {
      static SmallString<256> CurrentPath;
      if (CurrentPath.str().empty())
        sys::fs::current_path(CurrentPath);
      StringRef(CurrentPath)
          .split(Component, Separator, /*MaxSplit*/ -1, /*KeepEmpty*/ false);
    } else {
      BasePath.split(Component, Separator, /*MaxSplit*/ -1,
                     /*KeepEmpty*/ false);
    }
  }

  Path.split(Component, Separator, /*MaxSplit*/ -1, /*KeepEmpty*/ false);
}

void normalizePathSegments(SmallVector<StringRef, 16> &PathParts) {
  SmallVector<StringRef, 16> NormalizedPath;
  for (auto &Part : PathParts) {
    if (Part == ".") {
      continue;
    } else if (Part == "..") {
      if (!NormalizedPath.empty() && NormalizedPath.back() != "..") {
        NormalizedPath.pop_back();
      } else {
        NormalizedPath.push_back("..");
      }
    } else {
      NormalizedPath.push_back(Part);
    }
  }
  PathParts.swap(NormalizedPath);
}
#endif

std::optional<std::string> PathResolver::realpathCached(StringRef Path,
                                                        std::error_code &EC,
                                                        StringRef Base,
                                                        bool BaseIsResolved,
                                                        long SymLoopLevel) {
  EC.clear();

  if (Path.empty()) {
    EC = std::make_error_code(std::errc::no_such_file_or_directory);
    LLVM_DEBUG(dbgs() << "PathResolver::realpathCached: Empty path\n";);

    return std::nullopt;
  }

  if (SymLoopLevel <= 0) {
    EC = std::make_error_code(std::errc::too_many_symbolic_link_levels);
    LLVM_DEBUG(
        dbgs() << "PathResolver::realpathCached: Too many Symlink levels: "
               << Path << "\n";);

    return std::nullopt;
  }

  // If already cached - retun cached result
  bool isRelative = sys::path::is_relative(Path);
  if (!isRelative) {
    if (auto Cached = LibPathCache->read_realpath(Path)) {
      EC = Cached->ErrnoCode;
      if (EC) {
        LLVM_DEBUG(dbgs() << "PathResolver::realpathCached: Cached (error) for "
                          << Path << "\n";);
      } else {
        LLVM_DEBUG(
            dbgs() << "PathResolver::realpathCached: Cached (success) for "
                   << Path << " => " << Cached->canonicalPath << "\n";);
      }
      return Cached->canonicalPath.empty()
                 ? std::nullopt
                 : std::make_optional(Cached->canonicalPath);
    }
  }

  LLVM_DEBUG(dbgs() << "PathResolver::realpathCached: Resolving path: " << Path
                    << "\n";);

  // If result not in cache - call system function and cache result

  StringRef Separator(sys::path::get_separator());
  SmallString<256> Resolved(Separator);
#ifndef _WIN32
  SmallVector<StringRef, 16> Components;

  if (isRelative) {
    if (BaseIsResolved) {
      Resolved.assign(Base);
      LLVM_DEBUG(dbgs() << "  Using Resolved base: " << Base << "\n";);
    }
    createComponent(Path, Base, BaseIsResolved, Components);
  } else {
    Path.split(Components, Separator, /*MaxSplit*/ -1, /*KeepEmpty*/ false);
  }

  normalizePathSegments(Components);
  LLVM_DEBUG({
    for (auto &C : Components)
      dbgs() << " " << C << " ";

    dbgs() << "\n";
  });

  // Handle path list items
  for (const auto &Component : Components) {
    if (Component == ".")
      continue;
    if (Component == "..") {
      // collapse "a/b/../c" to "a/c"
      size_t S = Resolved.rfind(Separator);
      if (S != llvm::StringRef::npos)
        Resolved.resize(S);
      if (Resolved.empty())
        Resolved = Separator;
      continue;
    }

    size_t oldSize = Resolved.size();
    sys::path::append(Resolved, Component);
    const char *ResolvedPath = Resolved.c_str();
    LLVM_DEBUG(dbgs() << "  Processing Component: " << Component << " => "
                      << ResolvedPath << "\n";);
    mode_t st_mode = lstatCached(ResolvedPath);

    if (S_ISLNK(st_mode)) {
      LLVM_DEBUG(dbgs() << "    Found symlink: " << ResolvedPath << "\n";);

      auto SymlinkOpt = readlinkCached(ResolvedPath);
      if (!SymlinkOpt) {
        EC = std::make_error_code(std::errc::no_such_file_or_directory);
        LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{"", EC});
        LLVM_DEBUG(dbgs() << "    Failed to read symlink: " << ResolvedPath
                          << "\n";);

        return std::nullopt;
      }

      StringRef Symlink = *SymlinkOpt;
      LLVM_DEBUG(dbgs() << "    Symlink points to: " << Symlink << "\n";);

      std::string resolvedBase = "";
      if (sys::path::is_relative(Symlink)) {
        Resolved.resize(oldSize);
        resolvedBase = Resolved.str().str();
      }

      auto RealSymlink =
          realpathCached(Symlink, EC, resolvedBase,
                         /*BaseIsResolved=*/true, SymLoopLevel - 1);
      if (!RealSymlink) {
        LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{"", EC});
        LLVM_DEBUG(dbgs() << "    Failed to resolve symlink target: " << Symlink
                          << "\n";);

        return std::nullopt;
      }

      Resolved.assign(*RealSymlink);
      LLVM_DEBUG(dbgs() << "    Symlink Resolved to: " << Resolved << "\n";);

    } else if (st_mode == 0) {
      EC = std::make_error_code(std::errc::no_such_file_or_directory);
      LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{"", EC});
      LLVM_DEBUG(dbgs() << "    Component does not exist: " << ResolvedPath
                        << "\n";);

      return std::nullopt;
    }
  }
#else
  EC = sys::fs::real_path(Path, Resolved); // Windows fallback
#endif

  std::string Canonical = Resolved.str().str();
  {
    LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{
                                            Canonical,
                                            std::error_code() // success
                                        });
  }
  LLVM_DEBUG(dbgs() << "PathResolver::realpathCached: Final Resolved: " << Path
                    << " => " << Canonical << "\n";);
  return Canonical;
}

void LibraryScanHelper::addBasePath(const std::string &Path, PathType K) {
  std::error_code EC;
  std::string Canon = resolveCanonical(Path, EC);
  if (EC) {
    LLVM_DEBUG(
        dbgs()
            << "LibraryScanHelper::addBasePath: Failed to canonicalize path: "
            << Path << "\n";);
    return;
  }
  std::unique_lock<std::shared_mutex> Lock(Mtx);
  if (LibSearchPaths.count(Canon)) {
    LLVM_DEBUG(dbgs() << "LibraryScanHelper::addBasePath: Already added: "
                      << Canon << "\n";);
    return;
  }
  K = K == PathType::Unknown ? classifyKind(Canon) : K;
  LibSearchPaths[Canon] = std::make_unique<LibrarySearchPath>(Canon, K);
  auto &SP = LibSearchPaths[Canon];

  if (K == PathType::User) {
    LLVM_DEBUG(dbgs() << "LibraryScanHelper::addBasePath: Added User path: "
                      << Canon << "\n";);
    UnscannedUsr.push_back(StringRef(SP->BasePath));
  } else {
    LLVM_DEBUG(dbgs() << "LibraryScanHelper::addBasePath: Added System path: "
                      << Canon << "\n";);
    UnscannedSys.push_back(StringRef(SP->BasePath));
  }
}

void LibraryScanHelper::getNextBatch(
    PathType K, size_t BatchSize,
    SmallVectorImpl<const LibrarySearchPath *> &Result) {
  auto &Queue = (K == PathType::User) ? UnscannedUsr : UnscannedSys;

  std::unique_lock<std::shared_mutex> Lock(Mtx);

  while (!Queue.empty() && (BatchSize == 0 || Result.size() < BatchSize)) {
    StringRef Base = Queue.front();
    auto It = LibSearchPaths.find(Base);
    if (It != LibSearchPaths.end()) {
      auto &SP = It->second;
      ScanState Expected = ScanState::NotScanned;
      if (SP->State.compare_exchange_strong(Expected, ScanState::Scanning)) {
        Result.push_back(SP.get());
      }
    }
    Queue.pop_front();
  }
}

bool LibraryScanHelper::isTrackedBasePath(StringRef Path) const {
  std::error_code EC;
  std::string Canon = resolveCanonical(Path, EC);
  if (EC)
    return false;

  std::shared_lock<std::shared_mutex> Lock(Mtx);
  return LibSearchPaths.count(Canon) > 0;
}

bool LibraryScanHelper::leftToScan(PathType K) const {
  std::shared_lock<std::shared_mutex> Lock(Mtx);
  for (const auto &KV : LibSearchPaths) {
    const auto &SP = KV.second;
    if (SP->Kind == K && SP->State == ScanState::NotScanned)
      return true;
  }
  return false;
}

void LibraryScanHelper::resetToScan() {
  std::shared_lock<std::shared_mutex> Lock(Mtx);

  for (auto &[_, SP] : LibSearchPaths) {
    ScanState Expected = ScanState::Scanned;

    if (!SP->State.compare_exchange_strong(Expected, ScanState::NotScanned))
      continue;

    auto &TargetList =
        (SP->Kind == PathType::User) ? UnscannedUsr : UnscannedSys;
    TargetList.emplace_back(SP->BasePath);
  }
}

std::string LibraryScanHelper::resolveCanonical(StringRef Path,
                                                std::error_code &EC) const {
  auto Canon = LibPathResolver->resolve(Path, EC);
  return EC ? Path.str() : *Canon;
}

PathType LibraryScanHelper::classifyKind(StringRef Path) const {
  // Detect home directory
  const char *Home = getenv("HOME");
  if (Home && Path.starts_with(Home))
    return PathType::User;

  static const std::array<std::string, 5> UserPrefixes = {
      "/usr/local",    // often used by users for manual installs
      "/opt/homebrew", // common on macOS
      "/opt/local",    // MacPorts
      "/home",         // Linux home dirs
      "/Users",        // macOS user dirs
  };

  for (const auto &Prefix : UserPrefixes) {
    if (Path.starts_with(Prefix))
      return PathType::User;
  }

  return PathType::System;
}

Expected<LibraryDepsInfo> parseMachODeps(const object::MachOObjectFile &Obj) {
  LibraryDepsInfo Libdeps;
  LLVM_DEBUG(dbgs() << "Parsing Mach-O dependencies...\n";);
  for (const auto &Command : Obj.load_commands()) {
    switch (Command.C.cmd) {
    case MachO::LC_LOAD_DYLIB: {
      MachO::dylib_command dylibCmd = Obj.getDylibIDLoadCommand(Command);
      const char *name = Command.Ptr + dylibCmd.dylib.name;
      Libdeps.addDep(name);
      LLVM_DEBUG(dbgs() << "  Found LC_LOAD_DYLIB: " << name << "\n";);
    } break;
    case MachO::LC_LOAD_WEAK_DYLIB:
    case MachO::LC_REEXPORT_DYLIB:
    case MachO::LC_LOAD_UPWARD_DYLIB:
    case MachO::LC_LAZY_LOAD_DYLIB:
      break;
    case MachO::LC_RPATH: {
      // Extract RPATH
      MachO::rpath_command rpathCmd = Obj.getRpathCommand(Command);
      const char *rpath = Command.Ptr + rpathCmd.path;
      LLVM_DEBUG(dbgs() << "  Found LC_RPATH: " << rpath << "\n";);

      SmallVector<StringRef, 4> RawPaths;
      SplitString(StringRef(rpath), RawPaths,
                  sys::EnvPathSeparator == ':' ? ":" : ";");

      for (const auto &raw : RawPaths) {
        Libdeps.addRPath(raw.str()); // Convert to std::string
        LLVM_DEBUG(dbgs() << "    Parsed RPATH entry: " << raw << "\n";);
      }
      break;
    }
    }
  }

  return Expected<LibraryDepsInfo>(std::move(Libdeps));
}

template <class ELFT>
static Expected<StringRef> getDynamicStrTab(const object::ELFFile<ELFT> &Elf) {
  auto DynamicEntriesOrError = Elf.dynamicEntries();
  if (!DynamicEntriesOrError)
    return DynamicEntriesOrError.takeError();

  for (const typename ELFT::Dyn &Dyn : *DynamicEntriesOrError) {
    if (Dyn.d_tag == ELF::DT_STRTAB) {
      auto MappedAddrOrError = Elf.toMappedAddr(Dyn.getPtr());
      if (!MappedAddrOrError)
        return MappedAddrOrError.takeError();
      return StringRef(reinterpret_cast<const char *>(*MappedAddrOrError));
    }
  }

  // If the dynamic segment is not present, we fall back on the sections.
  auto SectionsOrError = Elf.sections();
  if (!SectionsOrError)
    return SectionsOrError.takeError();

  for (const typename ELFT::Shdr &Sec : *SectionsOrError) {
    if (Sec.sh_type == ELF::SHT_DYNSYM)
      return Elf.getStringTableForSymtab(Sec);
  }

  return make_error<StringError>("dynamic string table not found",
                                 inconvertibleErrorCode());
}

template <typename ELFT>
Expected<LibraryDepsInfo> parseELF(const object::ELFFile<ELFT> &Elf) {
  LibraryDepsInfo Deps;
  Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf);
  if (!StrTabOrErr)
    return StrTabOrErr.takeError();

  const char *Data = StrTabOrErr->data();

  auto DynamicEntriesOrError = Elf.dynamicEntries();
  if (!DynamicEntriesOrError) {
    return DynamicEntriesOrError.takeError();
  }

  for (const typename ELFT::Dyn &Dyn : *DynamicEntriesOrError) {
    switch (Dyn.d_tag) {
    case ELF::DT_NEEDED:
      Deps.addDep(Data + Dyn.d_un.d_val);
      break;
    case ELF::DT_RPATH: {
      SmallVector<StringRef, 4> RawPaths;
      SplitString(Data + Dyn.d_un.d_val, RawPaths,
                  sys::EnvPathSeparator == ':' ? ":" : ";");
      for (const auto &raw : RawPaths)
        Deps.addRPath(raw.str());
      break;
    }
    case ELF::DT_RUNPATH: {
      SmallVector<StringRef, 4> RawPaths;
      SplitString(Data + Dyn.d_un.d_val, RawPaths,
                  sys::EnvPathSeparator == ':' ? ":" : ";");
      for (const auto &raw : RawPaths)
        Deps.addRunPath(raw.str());
      break;
    }
    case ELF::DT_FLAGS_1:
      // Check if this is not a pie executable.
      if (Dyn.d_un.d_val & ELF::DF_1_PIE)
        Deps.isPIE = true;
      break;
      // (Dyn.d_tag == ELF::DT_NULL) continue;
      // (Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER)
    default:
      break;
    }
  }

  return Expected<LibraryDepsInfo>(std::move(Deps));
}

Expected<LibraryDepsInfo> parseELFDeps(const object::ELFObjectFileBase &Obj) {
  using namespace object;
  LLVM_DEBUG(dbgs() << "parseELFDeps: Detected ELF object\n";);
  if (const auto *ELF = dyn_cast<ELF32LEObjectFile>(&Obj))
    return parseELF(ELF->getELFFile());
  else if (const auto *ELF = dyn_cast<ELF32BEObjectFile>(&Obj))
    return parseELF(ELF->getELFFile());
  else if (const auto *ELF = dyn_cast<ELF64LEObjectFile>(&Obj))
    return parseELF(ELF->getELFFile());
  else if (const auto *ELF = dyn_cast<ELF64BEObjectFile>(&Obj))
    return parseELF(ELF->getELFFile());

  LLVM_DEBUG(dbgs() << "parseELFDeps: Unknown ELF format\n";);
  return createStringError(std::errc::not_supported, "Unknown ELF format");
}

Expected<LibraryDepsInfo> parseDependencies(StringRef FilePath,
                                            object::ObjectFile *Obj) {

  if (auto *elfObj = dyn_cast<object::ELFObjectFileBase>(Obj)) {
    LLVM_DEBUG(dbgs() << "extractDeps: File " << FilePath
                      << " is an ELF object\n";);

    return parseELFDeps(*elfObj);
  }

  if (auto *macho = dyn_cast<object::MachOObjectFile>(Obj)) {
    LLVM_DEBUG(dbgs() << "extractDeps: File " << FilePath
                      << " is a Mach-O object\n";);
    return parseMachODeps(*macho);
  }

  if (Obj->isCOFF()) {
    // TODO: COFF support
    return LibraryDepsInfo();
  }

  LLVM_DEBUG(dbgs() << "extractDeps: Unsupported binary format for file "
                    << FilePath << "\n";);
  return createStringError(inconvertibleErrorCode(),
                           "Unsupported binary format: %s",
                           FilePath.str().c_str());
}

Expected<LibraryDepsInfo> LibraryScanner::extractDeps(StringRef FilePath) {
  LLVM_DEBUG(dbgs() << "extractDeps: Attempting to open file " << FilePath
                    << "\n";);
  //  check cache first
  if (auto Cached = ObjCache.take(FilePath)) {
    auto ObjOrErr = Cached->getObjectFile();
    if (!ObjOrErr)
      return ObjOrErr.takeError();
    return parseDependencies(FilePath, &*ObjOrErr);
  }

  // fall back to normal loading
  ObjectFileLoader ObjLoader(FilePath);
  auto ObjOrErr = ObjLoader.getObjectFile();
  if (!ObjOrErr) {
    LLVM_DEBUG(dbgs() << "extractDeps: Failed to open " << FilePath << "\n";);
    return ObjOrErr.takeError();
  }

  return parseDependencies(FilePath, &*ObjOrErr);
}

bool LibraryScanner::shouldScan(StringRef FilePath, bool IsResolvingDep) {
  LLVM_DEBUG(dbgs() << "[shouldScan] Checking: " << FilePath << "\n";);

  LibraryPathCache &Cache = ScanHelper.getCache();
  // [1] Skip if we've already seen this path (via cache)
  if (Cache.hasSeen(FilePath)) {
    LLVM_DEBUG(dbgs() << "  -> Skipped: already seen.\n";);
    return false;
  }

  // [2] Already tracked in LibraryManager?
  /*if (LibMgr.hasLibrary(FilePath)) {
    LLVM_DEBUG(dbgs() << "  -> Skipped: already tracked by LibraryManager.\n";);
    return false;
  }*/

  // [3] Skip if it's not a shared library.
  if (!IsResolvingDep && !Validator.isSharedLibrary(FilePath)) {
    LLVM_DEBUG(dbgs() << "  -> Skipped: not a shared library.\n";);
    return false;
  }

  // Mark seen this path
  Cache.markSeen(FilePath.str());

  // [4] Run user-defined hook (default: always true)
  if (!ShouldScanCall(FilePath)) {
    LLVM_DEBUG(dbgs() << "  -> Skipped: user-defined hook rejected.\n";);
    return false;
  }

  LLVM_DEBUG(dbgs() << "  -> Accepted: ready to scan " << FilePath << "\n";);
  return true;
}

void LibraryScanner::handleLibrary(StringRef FilePath, PathType K, int level) {
  LLVM_DEBUG(dbgs() << "LibraryScanner::handleLibrary: Scanning: " << FilePath
                    << ", level=" << level << "\n";);
  if (!shouldScan(FilePath, level > 0)) {
    LLVM_DEBUG(dbgs() << "  Skipped (shouldScan returned false): " << FilePath
                      << "\n";);
    return;
  }

  auto DepsOrErr = extractDeps(FilePath);
  if (!DepsOrErr) {
    LLVM_DEBUG(dbgs() << "  Failed to extract deps for: " << FilePath << "\n";);
    handleError(DepsOrErr.takeError());
    return;
  }

  LibraryDepsInfo &Deps = *DepsOrErr;

  LLVM_DEBUG({
    dbgs() << "    Found deps : \n";
    for (const auto &dep : Deps.deps)
      dbgs() << "        : " << dep << "\n";
    dbgs() << "    Found @rpath : " << Deps.rpath.size() << "\n";
    for (const auto &r : Deps.rpath)
      dbgs() << "     : " << r << "\n";
    dbgs() << "    Found @runpath : \n";
    for (const auto &r : Deps.runPath)
      dbgs() << "     : " << r << "\n";
  });

  if (Deps.isPIE && level == 0) {
    LLVM_DEBUG(dbgs() << "  Skipped PIE executable at top level: " << FilePath
                      << "\n";);

    return;
  }

  bool Added = LibMgr.addLibrary(FilePath.str(), K);
  if (!Added) {
    LLVM_DEBUG(dbgs() << "  Already added: " << FilePath << "\n";);
    return;
  }

  // Heuristic 1: No RPATH/RUNPATH, skip deps
  if (Deps.rpath.empty() && Deps.runPath.empty()) {
    LLVM_DEBUG(
        dbgs() << "LibraryScanner::handleLibrary: Skipping deps (Heuristic1): "
               << FilePath << "\n";);
    return;
  }

  // Heuristic 2: All RPATH and RUNPATH already tracked
  auto allTracked = [&](const auto &Paths) {
    LLVM_DEBUG(dbgs() << "   Checking : " << Paths.size() << "\n";);
    return std::all_of(Paths.begin(), Paths.end(), [&](StringRef P) {
      LLVM_DEBUG(dbgs() << "      Checking isTrackedBasePath : " << P << "\n";);
      return ScanHelper.isTrackedBasePath(
          DylibResolver::resolvelinkerFlag(P, FilePath));
    });
  };

  if (allTracked(Deps.rpath) && allTracked(Deps.runPath)) {
    LLVM_DEBUG(
        dbgs() << "LibraryScanner::handleLibrary: Skipping deps (Heuristic2): "
               << FilePath << "\n";);
    return;
  }

  DylibResolver Resolver(Validator);
  Resolver.configure(FilePath,
                     {{Deps.rpath, SearchPathType::RPath},
                      {ScanHelper.getSearchPaths(), SearchPathType::UsrOrSys},
                      {Deps.runPath, SearchPathType::RunPath}});
  for (StringRef Dep : Deps.deps) {
    LLVM_DEBUG(dbgs() << "  Resolving dep: " << Dep << "\n";);
    auto DepFullOpt = Resolver.resolve(Dep);
    if (!DepFullOpt) {
      LLVM_DEBUG(dbgs() << "    Failed to resolve dep: " << Dep << "\n";);
      continue;
    }
    LLVM_DEBUG(dbgs() << "    Resolved dep to: " << *DepFullOpt << "\n";);

    handleLibrary(*DepFullOpt, K, level + 1);
  }
}

void LibraryScanner::scanBaseDir(LibrarySearchPath *SP) {
  if (!sys::fs::is_directory(SP->BasePath) || SP->BasePath.empty()) {
    LLVM_DEBUG(
        dbgs() << "LibraryScanner::scanBaseDir: Invalid or empty basePath: "
               << SP->BasePath << "\n";);
    return;
  }

  LLVM_DEBUG(dbgs() << "LibraryScanner::scanBaseDir: Scanning directory: "
                    << SP->BasePath << "\n";);
  std::error_code EC;

  SP->State.store(ScanState::Scanning);

  for (sys::fs::directory_iterator It(SP->BasePath, EC), end; It != end && !EC;
       It.increment(EC)) {
    auto Entry = *It;
    if (!Entry.status())
      continue;

    auto Status = *Entry.status();
    if (sys::fs::is_regular_file(Status) || sys::fs::is_symlink_file(Status)) {
      LLVM_DEBUG(dbgs() << "  Found file: " << Entry.path() << "\n";);

      std::string FinalPath;
      bool IsSymlink = sys::fs::is_symlink_file(Status);

      // Resolve symlink
      if (IsSymlink) {
        LLVM_DEBUG(dbgs() << "    Symlink → resolving...\n");

        auto CanonicalOpt = ScanHelper.resolve(Entry.path(), EC);
        if (EC || !CanonicalOpt) {
          LLVM_DEBUG(dbgs() << "    -> Skipped: resolve failed (EC="
                            << EC.message() << ")\n");
          continue;
        }

        FinalPath = std::move(*CanonicalOpt);

        LLVM_DEBUG(dbgs() << "    Canonical: " << FinalPath << "\n");

      } else {
        // make absolute
        SmallString<256> Abs(Entry.path());
        sys::fs::make_absolute(Abs);
        FinalPath = Abs.str().str();

        LLVM_DEBUG(dbgs() << "    Regular: absolute = " << FinalPath << "\n");
      }

      // Check if it's a directory — skip directories
      if (sys::fs::is_directory(Status)) {
        LLVM_DEBUG(dbgs() << "  -> Skipped: path is a directory.\n";);
        continue;
      }

      // async support ?
      handleLibrary(FinalPath, SP->Kind);
    }
  }

  SP->State.store(ScanState::Scanned);
}

void LibraryScanner::scanNext(PathType K, size_t BatchSize) {
  LLVM_DEBUG(dbgs() << "LibraryScanner::scanNext: Scanning next batch of size "
                    << BatchSize << " for kind "
                    << (K == PathType::User ? "User" : "System") << "\n";);

  SmallVector<const LibrarySearchPath *> SearchPaths;
  ScanHelper.getNextBatch(K, BatchSize, SearchPaths);
  for (const auto *SP : SearchPaths) {
    LLVM_DEBUG(dbgs() << "  Scanning unit with basePath: " << SP->BasePath
                      << "\n";);
    scanBaseDir(const_cast<LibrarySearchPath *>(SP));
  }
}
} // end namespace llvm::orc
