/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmFindLibraryCommand.h"

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <set>
#include <utility>

#include "cmsys/RegularExpression.hxx"

#include "cmGlobalGenerator.h"
#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"

class cmExecutionStatus;

cmFindLibraryCommand::cmFindLibraryCommand(cmExecutionStatus& status)
  : cmFindBase("find_library", status)
{
  this->EnvironmentPath = "LIB";
  this->NamesPerDirAllowed = true;
  this->VariableDocumentation = "Path to a library.";
  this->VariableType = cmStateEnums::FILEPATH;
}

// cmFindLibraryCommand
bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
{
  this->CMakePathName = "LIBRARY";

  if (!this->ParseArguments(argsIn)) {
    return false;
  }

  this->DebugMode = this->ComputeIfDebugModeWanted(this->VariableName);

  if (this->AlreadyDefined) {
    this->NormalizeFindResult();
    return true;
  }

  // add custom lib<qual> paths instead of using fixed lib32, lib64 or
  // libx32
  if (cmValue customLib = this->Makefile->GetDefinition(
        "CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX")) {
    this->AddArchitecturePaths(customLib->c_str());
  }
  // add special 32 bit paths if this is a 32 bit compile.
  else if (this->Makefile->PlatformIs32Bit() &&
           this->Makefile->GetState()->GetGlobalPropertyAsBool(
             "FIND_LIBRARY_USE_LIB32_PATHS")) {
    this->AddArchitecturePaths("32");
  }
  // add special 64 bit paths if this is a 64 bit compile.
  else if (this->Makefile->PlatformIs64Bit() &&
           this->Makefile->GetState()->GetGlobalPropertyAsBool(
             "FIND_LIBRARY_USE_LIB64_PATHS")) {
    this->AddArchitecturePaths("64");
  }
  // add special 32 bit paths if this is an x32 compile.
  else if (this->Makefile->PlatformIsx32() &&
           this->Makefile->GetState()->GetGlobalPropertyAsBool(
             "FIND_LIBRARY_USE_LIBX32_PATHS")) {
    this->AddArchitecturePaths("x32");
  }

  std::string const library = this->FindLibrary();
  this->StoreFindResult(library);
  return true;
}

void cmFindLibraryCommand::AddArchitecturePaths(const char* suffix)
{
  std::vector<std::string> original;
  original.swap(this->SearchPaths);
  for (std::string const& o : original) {
    this->AddArchitecturePath(o, 0, suffix);
    if (this->DebugMode) {
      std::string msg = cmStrCat(
        "find_library(", this->VariableName, ") removed original suffix ", o,
        " from PATH_SUFFIXES while adding architecture paths for suffix '",
        suffix, "'");
      this->DebugMessage(msg);
    }
  }
}

static bool cmLibDirsLinked(std::string const& l, std::string const& r)
{
  // Compare the real paths of the two directories.
  // Since our caller only changed the trailing component of each
  // directory, the real paths can be the same only if at least one of
  // the trailing components is a symlink.  Use this as an optimization
  // to avoid excessive realpath calls.
  return (cmSystemTools::FileIsSymlink(l) ||
          cmSystemTools::FileIsSymlink(r)) &&
    cmSystemTools::GetRealPath(l) == cmSystemTools::GetRealPath(r);
}

void cmFindLibraryCommand::AddArchitecturePath(
  std::string const& dir, std::string::size_type start_pos, const char* suffix,
  bool fresh)
{
  std::string::size_type pos = dir.find("lib/", start_pos);

  if (pos != std::string::npos) {
    // Check for "lib".
    std::string lib = dir.substr(0, pos + 3);
    bool use_lib = cmSystemTools::FileIsDirectory(lib);

    // Check for "lib<suffix>" and use it first.
    std::string libX = lib + suffix;
    bool use_libX = cmSystemTools::FileIsDirectory(libX);

    // Avoid copies of the same directory due to symlinks.
    if (use_libX && use_lib && cmLibDirsLinked(libX, lib)) {
      use_libX = false;
    }

    if (use_libX) {
      libX += dir.substr(pos + 3);
      std::string::size_type libX_pos = pos + 3 + strlen(suffix) + 1;
      this->AddArchitecturePath(libX, libX_pos, suffix);
    }

    if (use_lib) {
      this->AddArchitecturePath(dir, pos + 3 + 1, suffix, false);
    }
  }

  if (fresh) {
    // Check for the original unchanged path.
    bool use_dir = cmSystemTools::FileIsDirectory(dir);

    // Check for <dir><suffix>/ and use it first.
    std::string dirX = dir + suffix;
    bool use_dirX = cmSystemTools::FileIsDirectory(dirX);

    // Avoid copies of the same directory due to symlinks.
    if (use_dirX && use_dir && cmLibDirsLinked(dirX, dir)) {
      use_dirX = false;
    }

    if (use_dirX) {
      dirX += "/";
      if (this->DebugMode) {
        std::string msg = cmStrCat(
          "find_library(", this->VariableName, ") added replacement path ",
          dirX, " to PATH_SUFFIXES for architecture suffix '", suffix, "'");
        this->DebugMessage(msg);
      }
      this->SearchPaths.push_back(std::move(dirX));
    }

    if (use_dir) {
      this->SearchPaths.push_back(dir);
      if (this->DebugMode) {
        std::string msg = cmStrCat(
          "find_library(", this->VariableName, ") added replacement path ",
          dir, " to PATH_SUFFIXES for architecture suffix '", suffix, "'");
        this->DebugMessage(msg);
      }
    }
  }
}

std::string cmFindLibraryCommand::FindLibrary()
{
  std::string library;
  if (this->SearchFrameworkFirst || this->SearchFrameworkOnly) {
    library = this->FindFrameworkLibrary();
  }
  if (library.empty() && !this->SearchFrameworkOnly) {
    library = this->FindNormalLibrary();
  }
  if (library.empty() && this->SearchFrameworkLast) {
    library = this->FindFrameworkLibrary();
  }
  return library;
}

struct cmFindLibraryHelper
{
  cmFindLibraryHelper(std::string debugName, cmMakefile* mf,
                      cmFindBase const* findBase);

  // Context information.
  cmMakefile* Makefile;
  cmFindBase const* FindBase;
  cmGlobalGenerator* GG;

  // List of valid prefixes and suffixes.
  cmList Prefixes;
  cmList Suffixes;
  std::string PrefixRegexStr;
  std::string SuffixRegexStr;

  // Keep track of the best library file found so far.
  using size_type = std::vector<std::string>::size_type;
  std::string BestPath;

  // Support for OpenBSD shared library naming: lib<name>.so.<major>.<minor>
  bool IsOpenBSD;

  bool DebugMode;

  // Current names under consideration.
  struct Name
  {
    bool TryRaw = false;
    std::string Raw;
    cmsys::RegularExpression Regex;
  };
  std::vector<Name> Names;

  // Current full path under consideration.
  std::string TestPath;

  void RegexFromLiteral(std::string& out, std::string const& in);
  void RegexFromList(std::string& out, cmList const& in);
  size_type GetPrefixIndex(std::string const& prefix)
  {
    return std::find(this->Prefixes.begin(), this->Prefixes.end(), prefix) -
      this->Prefixes.begin();
  }
  size_type GetSuffixIndex(std::string const& suffix)
  {
    return std::find(this->Suffixes.begin(), this->Suffixes.end(), suffix) -
      this->Suffixes.begin();
  }
  bool HasValidSuffix(std::string const& name);
  void AddName(std::string const& name);
  void SetName(std::string const& name);
  bool CheckDirectory(std::string const& path);
  bool CheckDirectoryForName(std::string const& path, Name& name);

  bool Validate(const std::string& path) const
  {
    return this->FindBase->Validate(path);
  }

  cmFindBaseDebugState DebugSearches;

  void DebugLibraryFailed(std::string const& name, std::string const& path)
  {
    if (this->DebugMode) {
      // To improve readability of the debug output, if there is only one
      // prefix/suffix, use the plain prefix/suffix instead of the regex.
      const auto& prefix = (this->Prefixes.size() == 1) ? this->Prefixes[0]
                                                        : this->PrefixRegexStr;
      const auto& suffix = (this->Suffixes.size() == 1) ? this->Suffixes[0]
                                                        : this->SuffixRegexStr;

      auto regexName = cmStrCat(prefix, name, suffix);
      this->DebugSearches.FailedAt(path, regexName);
    }
  }

  void DebugLibraryFound(std::string const& name, std::string const& path)
  {
    if (this->DebugMode) {
      auto regexName =
        cmStrCat(this->PrefixRegexStr, name, this->SuffixRegexStr);
      this->DebugSearches.FoundAt(path, regexName);
    }
  }
};

namespace {

std::string const& get_prefixes(cmMakefile* mf)
{
#ifdef _WIN32
  static std::string defaultPrefix = ";lib";
#else
  static std::string defaultPrefix = "lib";
#endif
  cmValue prefixProp = mf->GetDefinition("CMAKE_FIND_LIBRARY_PREFIXES");
  return (prefixProp) ? *prefixProp : defaultPrefix;
}

std::string const& get_suffixes(cmMakefile* mf)
{
#ifdef _WIN32
  static std::string defaultSuffix = ".lib;.dll.a;.a";
#elif defined(__APPLE__)
  static std::string defaultSuffix = ".tbd;.dylib;.so;.a";
#elif defined(__hpux)
  static std::string defaultSuffix = ".sl;.so;.a";
#else
  static std::string defaultSuffix = ".so;.a";
#endif
  cmValue suffixProp = mf->GetDefinition("CMAKE_FIND_LIBRARY_SUFFIXES");
  return (suffixProp) ? *suffixProp : defaultSuffix;
}
}
cmFindLibraryHelper::cmFindLibraryHelper(std::string debugName, cmMakefile* mf,
                                         cmFindBase const* base)
  : Makefile(mf)
  , FindBase(base)
  , DebugMode(base->DebugModeEnabled())
  , DebugSearches(std::move(debugName), base)
{
  this->GG = this->Makefile->GetGlobalGenerator();

  // Collect the list of library name prefixes/suffixes to try.
  std::string const& prefixes_list = get_prefixes(this->Makefile);
  std::string const& suffixes_list = get_suffixes(this->Makefile);

  this->Prefixes.assign(prefixes_list, cmList::EmptyElements::Yes);
  this->Suffixes.assign(suffixes_list, cmList::EmptyElements::Yes);
  this->RegexFromList(this->PrefixRegexStr, this->Prefixes);
  this->RegexFromList(this->SuffixRegexStr, this->Suffixes);

  // Check whether to use OpenBSD-style library version comparisons.
  this->IsOpenBSD = this->Makefile->GetState()->GetGlobalPropertyAsBool(
    "FIND_LIBRARY_USE_OPENBSD_VERSIONING");
}

void cmFindLibraryHelper::RegexFromLiteral(std::string& out,
                                           std::string const& in)
{
  for (char ch : in) {
    if (ch == '[' || ch == ']' || ch == '(' || ch == ')' || ch == '\\' ||
        ch == '.' || ch == '*' || ch == '+' || ch == '?' || ch == '-' ||
        ch == '^' || ch == '$') {
      out += "\\";
    }
#if defined(_WIN32) || defined(__APPLE__)
    out += static_cast<char>(tolower(ch));
#else
    out += ch;
#endif
  }
}

void cmFindLibraryHelper::RegexFromList(std::string& out, cmList const& in)
{
  // Surround the list in parens so the '|' does not apply to anything
  // else and the result can be checked after matching.
  out += "(";
  const char* sep = "";
  for (auto const& s : in) {
    // Separate from previous item.
    out += sep;
    sep = "|";

    // Append this item.
    this->RegexFromLiteral(out, s);
  }
  out += ")";
}

bool cmFindLibraryHelper::HasValidSuffix(std::string const& name)
{
  for (std::string suffix : this->Suffixes) {
    if (name.length() <= suffix.length()) {
      continue;
    }
    // Check if the given name ends in a valid library suffix.
    if (name.substr(name.size() - suffix.length()) == suffix) {
      return true;
    }
    // Check if a valid library suffix is somewhere in the name,
    // this may happen e.g. for versioned shared libraries: libfoo.so.2
    suffix += ".";
    if (name.find(suffix) != std::string::npos) {
      return true;
    }
  }
  return false;
}

void cmFindLibraryHelper::AddName(std::string const& name)
{
  Name entry;

  // Consider checking the raw name too.
  entry.TryRaw = this->HasValidSuffix(name);
  entry.Raw = name;

  // Build a regular expression to match library names.
  std::string regex = cmStrCat('^', this->PrefixRegexStr);
  this->RegexFromLiteral(regex, name);
  regex += this->SuffixRegexStr;
  if (this->IsOpenBSD) {
    regex += "(\\.[0-9]+\\.[0-9]+)?";
  }
  regex += "$";
  entry.Regex.compile(regex);
  this->Names.push_back(std::move(entry));
}

void cmFindLibraryHelper::SetName(std::string const& name)
{
  this->Names.clear();
  this->AddName(name);
}

bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
{
  for (Name& i : this->Names) {
    if (this->CheckDirectoryForName(path, i)) {
      return true;
    }
  }
  return false;
}

bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
                                                Name& name)
{
  // If the original library name provided by the user matches one of
  // the suffixes, try it first.  This allows users to search
  // specifically for a static library on some platforms (on MS tools
  // one cannot tell just from the library name whether it is a static
  // library or an import library).
  if (name.TryRaw) {
    this->TestPath = cmStrCat(path, name.Raw);

    const bool exists = cmSystemTools::FileExists(this->TestPath, true);
    if (!exists) {
      this->DebugLibraryFailed(name.Raw, path);
    } else {
      auto testPath = cmSystemTools::CollapseFullPath(this->TestPath);
      if (this->Validate(testPath)) {
        this->DebugLibraryFound(name.Raw, path);
        this->BestPath = testPath;
        return true;
      }
      this->DebugLibraryFailed(name.Raw, path);
    }
  }

  // No library file has yet been found.
  size_type bestPrefix = this->Prefixes.size();
  size_type bestSuffix = this->Suffixes.size();
  unsigned int bestMajor = 0;
  unsigned int bestMinor = 0;

  // Search for a file matching the library name regex.
  std::string dir = path;
  cmSystemTools::ConvertToUnixSlashes(dir);
  std::set<std::string> const& files = this->GG->GetDirectoryContent(dir);
  for (std::string const& origName : files) {
#if defined(_WIN32) || defined(__APPLE__)
    std::string testName = cmSystemTools::LowerCase(origName);
#else
    std::string const& testName = origName;
#endif
    if (name.Regex.find(testName)) {
      this->TestPath = cmStrCat(path, origName);
      // Make sure the path is readable and is not a directory.
      if (cmSystemTools::FileExists(this->TestPath, true)) {
        if (!this->Validate(cmSystemTools::CollapseFullPath(this->TestPath))) {
          continue;
        }

        this->DebugLibraryFound(name.Raw, dir);
        // This is a matching file.  Check if it is better than the
        // best name found so far.  Earlier prefixes are preferred,
        // followed by earlier suffixes.  For OpenBSD, shared library
        // version extensions are compared.
        size_type prefix = this->GetPrefixIndex(name.Regex.match(1));
        size_type suffix = this->GetSuffixIndex(name.Regex.match(2));
        unsigned int major = 0;
        unsigned int minor = 0;
        if (this->IsOpenBSD) {
          sscanf(name.Regex.match(3).c_str(), ".%u.%u", &major, &minor);
        }
        if (this->BestPath.empty() || prefix < bestPrefix ||
            (prefix == bestPrefix && suffix < bestSuffix) ||
            (prefix == bestPrefix && suffix == bestSuffix &&
             (major > bestMajor ||
              (major == bestMajor && minor > bestMinor)))) {
          this->BestPath = this->TestPath;
          bestPrefix = prefix;
          bestSuffix = suffix;
          bestMajor = major;
          bestMinor = minor;
        }
      }
    }
  }

  if (this->BestPath.empty()) {
    this->DebugLibraryFailed(name.Raw, dir);
  } else {
    this->DebugLibraryFound(name.Raw, this->BestPath);
  }

  // Use the best candidate found in this directory, if any.
  return !this->BestPath.empty();
}

std::string cmFindLibraryCommand::FindNormalLibrary()
{
  if (this->NamesPerDir) {
    return this->FindNormalLibraryNamesPerDir();
  }
  return this->FindNormalLibraryDirsPerName();
}

std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
{
  // Search for all names in each directory.
  cmFindLibraryHelper helper(this->FindCommandName, this->Makefile, this);
  for (std::string const& n : this->Names) {
    helper.AddName(n);
  }
  // Search every directory.
  for (std::string const& sp : this->SearchPaths) {
    if (helper.CheckDirectory(sp)) {
      return helper.BestPath;
    }
  }
  // Couldn't find the library.
  return "";
}

std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName()
{
  // Search the entire path for each name.
  cmFindLibraryHelper helper(this->FindCommandName, this->Makefile, this);
  for (std::string const& n : this->Names) {
    // Switch to searching for this name.
    helper.SetName(n);

    // Search every directory.
    for (std::string const& sp : this->SearchPaths) {
      if (helper.CheckDirectory(sp)) {
        return helper.BestPath;
      }
    }
  }
  // Couldn't find the library.
  return "";
}

std::string cmFindLibraryCommand::FindFrameworkLibrary()
{
  if (this->NamesPerDir) {
    return this->FindFrameworkLibraryNamesPerDir();
  }
  return this->FindFrameworkLibraryDirsPerName();
}

std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir()
{
  std::string fwPath;
  // Search for all names in each search path.
  for (std::string const& d : this->SearchPaths) {
    for (std::string const& n : this->Names) {
      fwPath = cmStrCat(d, n, ".xcframework");
      if (cmSystemTools::FileIsDirectory(fwPath)) {
        auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
        if (this->Validate(finalPath)) {
          return finalPath;
        }
      }

      fwPath = cmStrCat(d, n, ".framework");
      if (cmSystemTools::FileIsDirectory(fwPath)) {
        auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
        if (this->Validate(finalPath)) {
          return finalPath;
        }
      }
    }
  }

  // No framework found.
  return "";
}

std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName()
{
  std::string fwPath;
  // Search for each name in all search paths.
  for (std::string const& n : this->Names) {
    for (std::string const& d : this->SearchPaths) {
      fwPath = cmStrCat(d, n, ".xcframework");
      if (cmSystemTools::FileIsDirectory(fwPath)) {
        auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
        if (this->Validate(finalPath)) {
          return finalPath;
        }
      }

      fwPath = cmStrCat(d, n, ".framework");
      if (cmSystemTools::FileIsDirectory(fwPath)) {
        auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
        if (this->Validate(finalPath)) {
          return finalPath;
        }
      }
    }
  }

  // No framework found.
  return "";
}

bool cmFindLibrary(std::vector<std::string> const& args,
                   cmExecutionStatus& status)
{
  return cmFindLibraryCommand(status).InitialPass(args);
}
