/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */

#include "cmPkgConfigResolver.h"

#include <algorithm>
#include <cstring>
#include <iterator>
#include <string>
#include <utility>
#include <vector>

#include <cm/optional>

#include "cmsys/String.h"

#include "cmOutputConverter.h"
#include "cmPkgConfigParser.h"
#include "cmStringAlgorithms.h"

namespace {

bool HasPrefix(std::string const& value, char const* prefix)
{
  std::size_t const len = std::strlen(prefix);
  return value.size() >= len && value.compare(0, len, prefix) == 0;
}

void AppendFlag(std::string& flagline, std::string const& flag)
{
  if (!flagline.empty()) {
    flagline += ' ';
  }
  flagline += flag;
}

bool IsSystemPath(std::string const& path,
                  std::vector<std::string> const& systemPaths)
{
  return std::find(systemPaths.begin(), systemPaths.end(), path) !=
    systemPaths.end();
}

std::vector<std::string> DefaultSystemIncludePaths()
{
  return std::vector<std::string>{ "/usr/include" };
}

std::vector<std::string> DefaultSystemLibraryPaths()
{
  return std::vector<std::string>{ "/usr/lib" };
}

std::vector<std::string> const& SystemCflags(cmPkgConfigEnv const& env,
                                             std::vector<std::string>& def)
{
  if (env.SysCflags) {
    return *env.SysCflags;
  }
  def = DefaultSystemIncludePaths();
  return def;
}

std::vector<std::string> const& SystemLibs(cmPkgConfigEnv const& env,
                                           std::vector<std::string>& def)
{
  if (env.SysLibs) {
    return *env.SysLibs;
  }
  def = DefaultSystemLibraryPaths();
  return def;
}

} // namespace

std::string cmPkgConfigResolver::VersionReqString(
  cmPkgConfigDependencySpec const& spec)
{
  switch (spec.Operation) {
    case cmPkgConfigDependencyOperation::None:
      return "";
    case cmPkgConfigDependencyOperation::LessThan:
      return cmStrCat('<', spec.Version);
    case cmPkgConfigDependencyOperation::LessThanEqual:
      return cmStrCat("<=", spec.Version);
    case cmPkgConfigDependencyOperation::Equal:
      return cmStrCat('=', spec.Version);
    case cmPkgConfigDependencyOperation::NotEqual:
      return cmStrCat("!=", spec.Version);
    case cmPkgConfigDependencyOperation::GreaterThanEqual:
      return cmStrCat(">=", spec.Version);
    case cmPkgConfigDependencyOperation::GreaterThan:
      return cmStrCat('>', spec.Version);
  }
  return "";
}

cmPkgConfigResolver::cmPkgConfigResolver(cmPkgConfigParser parser,
                                         cmPkgConfigEnv const& env,
                                         std::string const& pcFileDir)
  : Parser{ std::move(parser) }
  , Env{ &env }
{
  this->Parser.ParseComplete();
  this->ConfigureParser(pcFileDir);
}

cm::optional<cmPkgConfigResolver> cmPkgConfigResolver::Resolve(
  cmPkgConfigParser parser, cmPkgConfigEnv const& env, Strictness strictness,
  std::string const& pcFileDir)
{
  cmPkgConfigResolver resolver{ std::move(parser), env, pcFileDir };
  if (strictness != Strictness::BestEffort && !resolver.HasRequiredFields()) {
    return {};
  }
  if (strictness == Strictness::Strict && resolver.HasStrictConflicts()) {
    return {};
  }
  return resolver;
}

cm::optional<cmPkgConfigResolver> cmPkgConfigResolver::ResolveStrict(
  cmPkgConfigParser parser, cmPkgConfigEnv const& env,
  std::string const& pcFileDir)
{
  return Resolve(std::move(parser), env, Strictness::Strict, pcFileDir);
}

cm::optional<cmPkgConfigResolver> cmPkgConfigResolver::ResolvePermissive(
  cmPkgConfigParser parser, cmPkgConfigEnv const& env,
  std::string const& pcFileDir)
{
  return Resolve(std::move(parser), env, Strictness::Permissive, pcFileDir);
}

cmPkgConfigResolver cmPkgConfigResolver::ResolveBestEffort(
  cmPkgConfigParser parser, cmPkgConfigEnv const& env,
  std::string const& pcFileDir)
{
  return cmPkgConfigResolver{ std::move(parser), env, pcFileDir };
}

void cmPkgConfigResolver::ConfigureParser(std::string const& pcFileDir)
{
  if (this->Env->SysrootDir) {
    this->Parser.SetVariable(
      "pc_sysrootdir",
      cmOutputConverter::EscapeForShell(*this->Env->SysrootDir,
                                        cmOutputConverter::Shell_Flag_IsUnix));
  } else {
    this->Parser.SetVariable("pc_sysrootdir", "/");
  }

  if (this->Env->TopBuildDir) {
    this->Parser.SetVariable(
      "pc_top_builddir",
      cmOutputConverter::EscapeForShell(*this->Env->TopBuildDir,
                                        cmOutputConverter::Shell_Flag_IsUnix));
  }

  this->Parser.SetVariable("pcfiledir",
                           cmOutputConverter::EscapeForShell(
                             pcFileDir, cmOutputConverter::Shell_Flag_IsUnix));
}

bool cmPkgConfigResolver::HasRequiredFields() const
{
  return this->Parser.HasProperty("Name") &&
    this->Parser.HasProperty("Description") &&
    this->Parser.HasProperty("Version");
}

bool cmPkgConfigResolver::HasStrictConflicts() const
{
  return (this->Parser.HasProperty("Cflags") &&
          this->Parser.HasProperty("CFlags")) ||
    (this->Parser.HasProperty("Cflags.private") &&
     this->Parser.HasProperty("CFlags.private"));
}

std::string cmPkgConfigResolver::Literal(std::string const& key) const
{
  return this->Parser.GetLiteral(key);
}

std::string cmPkgConfigResolver::Name() const
{
  return this->Literal("Name");
}

std::string cmPkgConfigResolver::Description() const
{
  return this->Literal("Description");
}

std::string cmPkgConfigResolver::Version() const
{
  return this->Literal("Version");
}

std::vector<std::string> cmPkgConfigResolver::Fragments(
  std::string const& key) const
{
  return this->Parser.GetFragments(key);
}

std::vector<cmPkgConfigDependencySpec> cmPkgConfigResolver::Dependencies(
  std::string const& key) const
{
  return this->Parser.GetDependencies(key);
}

std::vector<cmPkgConfigDependencySpec> cmPkgConfigResolver::Conflicts() const
{
  return this->Dependencies("Conflicts");
}

std::vector<cmPkgConfigDependencySpec> cmPkgConfigResolver::Provides() const
{
  return this->Dependencies("Provides");
}

std::vector<cmPkgConfigDependencySpec> cmPkgConfigResolver::Requires(
  bool priv) const
{
  return this->Dependencies(priv ? "Requires.private" : "Requires");
}

cmPkgConfigCflagsResult cmPkgConfigResolver::Cflags(bool priv) const
{
  auto flags = this->Fragments(priv ? "Cflags.private" : "Cflags");
  auto alt = this->Fragments(priv ? "CFlags.private" : "CFlags");
  flags.insert(flags.end(), alt.begin(), alt.end());
  return MangleCflags(flags, *this->Env);
}

cmPkgConfigLibsResult cmPkgConfigResolver::Libs(bool priv) const
{
  return MangleLibs(this->Fragments(priv ? "Libs.private" : "Libs"),
                    *this->Env);
}

cmPkgConfigCflagsResult cmPkgConfigResolver::MangleCflags(
  std::vector<std::string> const& flags, cmPkgConfigEnv const& env)
{
  cmPkgConfigCflagsResult result;
  std::vector<std::string> defaultSystemPaths;
  auto const& systemPaths = SystemCflags(env, defaultSystemPaths);

  for (auto const& flag : flags) {
    std::string mangled = flag;
    if (HasPrefix(flag, "-I") && env.SysrootDir) {
      mangled = Reroot(flag, "-I", *env.SysrootDir);
    }

    if (HasPrefix(mangled, "-I")) {
      if (!env.AllowSysCflags &&
          IsSystemPath(mangled.substr(2), systemPaths)) {
        continue;
      }
      AppendFlag(result.Flagline, mangled);
      result.Includes.push_back(mangled);
    } else {
      AppendFlag(result.Flagline, mangled);
      result.CompileOptions.push_back(mangled);
    }
  }

  return result;
}

cmPkgConfigLibsResult cmPkgConfigResolver::MangleLibs(
  std::vector<std::string> const& flags, cmPkgConfigEnv const& env)
{
  cmPkgConfigLibsResult result;
  std::vector<std::string> defaultSystemPaths;
  auto const& systemPaths = SystemLibs(env, defaultSystemPaths);

  for (auto const& flag : flags) {
    std::string mangled = flag;
    if (HasPrefix(flag, "-L") && env.SysrootDir) {
      mangled = Reroot(flag, "-L", *env.SysrootDir);
    }

    if (HasPrefix(mangled, "-L")) {
      if (!env.AllowSysLibs && IsSystemPath(mangled.substr(2), systemPaths)) {
        continue;
      }
      AppendFlag(result.Flagline, mangled);
      result.LibDirs.push_back(mangled);
    } else if (HasPrefix(mangled, "-l")) {
      AppendFlag(result.Flagline, mangled);
      result.LibNames.push_back(mangled);
    } else {
      AppendFlag(result.Flagline, mangled);
      result.LinkOptions.push_back(mangled);
    }
  }

  return result;
}

std::string cmPkgConfigResolver::Reroot(std::string const& flag,
                                        char const* prefix,
                                        std::string const& sysroot)
{
  std::string result = prefix;
  result += sysroot;
  result += flag.substr(std::strlen(prefix));
  return result;
}

void cmPkgConfigResolver::ReplaceSep(std::string& list)
{
#ifndef _WIN32
  std::replace(list.begin(), list.end(), ':', ';');
#else
  static_cast<void>(list);
#endif
}

bool cmPkgConfigResolver::CheckVersion(
  cmPkgConfigDependencySpec const& desired, std::string const& provided)
{
  if (desired.Operation == cmPkgConfigDependencyOperation::None) {
    return true;
  }

  auto check_with_op = [&](int comp) -> bool {
    switch (desired.Operation) {
      case cmPkgConfigDependencyOperation::Equal:
        return comp == 0;
      case cmPkgConfigDependencyOperation::NotEqual:
        return comp != 0;
      case cmPkgConfigDependencyOperation::GreaterThan:
        return comp < 0;
      case cmPkgConfigDependencyOperation::GreaterThanEqual:
        return comp <= 0;
      case cmPkgConfigDependencyOperation::LessThan:
        return comp > 0;
      case cmPkgConfigDependencyOperation::LessThanEqual:
        return comp >= 0;
      default:
        return true;
    }
  };

  if (desired.Version == provided) {
    return check_with_op(0);
  }

  auto a_cur = desired.Version.begin();
  auto a_end = desired.Version.end();

  auto b_cur = provided.begin();
  auto b_end = provided.end();

  while (a_cur != a_end && b_cur != b_end) {
    while (a_cur != a_end && !cmsysString_isalnum(*a_cur) && *a_cur != '~') {
      ++a_cur;
    }

    while (b_cur != b_end && !cmsysString_isalnum(*b_cur) && *b_cur != '~') {
      ++b_cur;
    }

    if (a_cur == a_end || b_cur == b_end) {
      break;
    }

    if (*a_cur == '~' || *b_cur == '~') {
      if (*a_cur != '~') {
        return check_with_op(1);
      }

      if (*b_cur != '~') {
        return check_with_op(-1);
      }

      ++a_cur;
      ++b_cur;
      continue;
    }

    auto a_seg = a_cur;
    auto b_seg = b_cur;
    bool is_num;

    if (cmsysString_isdigit(*a_cur)) {
      is_num = true;
      while (a_cur != a_end && cmsysString_isdigit(*a_cur)) {
        ++a_cur;
      }

      while (b_cur != b_end && cmsysString_isdigit(*b_cur)) {
        ++b_cur;
      }

    } else {
      is_num = false;
      while (a_cur != a_end && cmsysString_isalpha(*a_cur)) {
        ++a_cur;
      }

      while (b_cur != b_end && cmsysString_isalpha(*b_cur)) {
        ++b_cur;
      }
    }

    auto a_len = std::distance(a_seg, a_cur);
    auto b_len = std::distance(b_seg, b_cur);

    if (!b_len) {
      return check_with_op(is_num ? 1 : -1);
    }

    if (is_num) {
      while (a_seg != a_cur && *a_seg == '0') {
        ++a_seg;
      }

      while (b_seg != b_cur && *b_seg == '0') {
        ++b_seg;
      }

      a_len = std::distance(a_seg, a_cur);
      b_len = std::distance(b_seg, b_cur);

      if (a_len != b_len) {
        return check_with_op(a_len > b_len ? 1 : -1);
      }

      auto cmp = std::memcmp(&*a_seg, &*b_seg, a_len);
      if (cmp) {
        return check_with_op(cmp);
      }
    } else {
      auto cmp = std::memcmp(&*a_seg, &*b_seg, std::min(a_len, b_len));
      if (cmp) {
        return check_with_op(cmp);
      }

      if (a_len != b_len) {
        return check_with_op(a_len > b_len ? 1 : -1);
      }
    }
  }

  if (a_cur == a_end) {
    if (b_cur == b_end) {
      return check_with_op(0);
    }
    return check_with_op(-1);
  }

  return check_with_op(1);
}
