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

#include <ostream>
#include <string>
#include <utility>
#include <vector>

#include "cmDiagnosticContext.h"
#include "cmGeneratorExpression.h"
#include "cmInstallGenerator.h"
#include "cmInstallType.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmScriptGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmake.h"

cmInstallRuntimeDependencySetGenerator::cmInstallRuntimeDependencySetGenerator(
  DependencyType type, cmInstallRuntimeDependencySet* dependencySet,
  std::vector<std::string> installRPaths, bool noInstallRPath,
  std::string installNameDir, bool noInstallName, char const* depsVar,
  char const* rpathPrefix, char const* tmpVarPrefix, std::string destination,
  std::vector<std::string> const& configurations, std::string component,
  std::string permissions, MessageLevel message, bool excludeFromAll,
  cmDiagnosticContext context)
  : cmInstallGenerator(std::move(destination), configurations,
                       std::move(component), message, excludeFromAll, false,
                       std::move(context))
  , Type(type)
  , DependencySet(dependencySet)
  , InstallRPaths(std::move(installRPaths))
  , NoInstallRPath(noInstallRPath)
  , InstallNameDir(std::move(installNameDir))
  , NoInstallName(noInstallName)
  , Permissions(std::move(permissions))
  , DepsVar(depsVar)
  , RPathPrefix(rpathPrefix)
  , TmpVarPrefix(tmpVarPrefix)
{
  this->ActionsPerConfig = true;
}

bool cmInstallRuntimeDependencySetGenerator::Compute(cmLocalGenerator* lg)
{
  this->LocalGenerator = lg;
  return true;
}

void cmInstallRuntimeDependencySetGenerator::GenerateScriptForConfig(
  std::ostream& os, std::string const& config, Indent indent)
{
  if (!this->LocalGenerator->GetMakefile()
         ->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL")
         .empty() &&
      !this->NoInstallName) {
    std::string installNameDir = "@rpath/";
    if (!this->InstallNameDir.empty()) {
      installNameDir = this->InstallNameDir;
      cmGeneratorExpression::ReplaceInstallPrefix(installNameDir,
                                                  "${CMAKE_INSTALL_PREFIX}");
      installNameDir = cmGeneratorExpression::Evaluate(
        installNameDir, this->LocalGenerator, config);
      if (installNameDir.empty()) {
        this->LocalGenerator->GetMakefile()->GetCMakeInstance()->IssueMessage(
          MessageType::FATAL_ERROR,
          "INSTALL_NAME_DIR argument must not evaluate to an "
          "empty string",
          this->Context.GetBacktrace());
        return;
      }
      if (installNameDir.back() != '/') {
        installNameDir += '/';
      }
    }
    os << indent << "set(" << this->TmpVarPrefix << "_install_name_dir \""
       << installNameDir << "\")\n";
  }

  os << indent << "foreach(" << this->TmpVarPrefix << "_dep IN LISTS "
     << this->DepsVar << ")\n";

  if (!this->LocalGenerator->GetMakefile()
         ->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL")
         .empty()) {
    std::vector<std::string> evaluatedRPaths;
    for (auto const& rpath : this->InstallRPaths) {
      std::string result =
        cmGeneratorExpression::Evaluate(rpath, this->LocalGenerator, config);
      if (!result.empty()) {
        evaluatedRPaths.push_back(std::move(result));
      }
    }

    switch (this->Type) {
      case DependencyType::Library:
        this->GenerateAppleLibraryScript(os, config, evaluatedRPaths,
                                         indent.Next());
        break;
      case DependencyType::Framework:
        this->GenerateAppleFrameworkScript(os, config, evaluatedRPaths,
                                           indent.Next());
        break;
    }
  } else {
    std::string depVar = cmStrCat(this->TmpVarPrefix, "_dep");

    this->AddInstallRule(
      os, this->GetDestination(config), cmInstallType_SHARED_LIBRARY, {},
      false, this->Permissions.c_str(), nullptr, nullptr,
      " FOLLOW_SYMLINK_CHAIN", indent.Next(), depVar.c_str());

    if (this->LocalGenerator->GetMakefile()->GetSafeDefinition(
          "CMAKE_SYSTEM_NAME") == "Linux" &&
        !this->NoInstallRPath) {
      std::string evaluatedRPath;
      for (auto const& rpath : this->InstallRPaths) {
        std::string result =
          cmGeneratorExpression::Evaluate(rpath, this->LocalGenerator, config);
        if (!result.empty()) {
          if (evaluatedRPath.empty()) {
            evaluatedRPath = std::move(result);
          } else {
            evaluatedRPath += ':';
            evaluatedRPath += result;
          }
        }
      }

      os << indent.Next() << "get_filename_component(" << this->TmpVarPrefix
         << "_dep_name \"${" << this->TmpVarPrefix << "_dep}\" NAME)\n";
      if (evaluatedRPath.empty()) {
        os << indent.Next() << "file(RPATH_REMOVE FILE \""
           << GetDestDirPath(
                ConvertToAbsoluteDestination(this->GetDestination(config)))
           << "/${" << this->TmpVarPrefix << "_dep_name}\")\n";
      } else {
        os << indent.Next() << "file(RPATH_SET FILE \""
           << GetDestDirPath(
                ConvertToAbsoluteDestination(this->GetDestination(config)))
           << "/${" << this->TmpVarPrefix << "_dep_name}\" NEW_RPATH "
           << cmScriptGenerator::Quote(evaluatedRPath) << ")\n";
      }
    }
  }

  os << indent << "endforeach()\n";
}

void cmInstallRuntimeDependencySetGenerator::GenerateAppleLibraryScript(
  std::ostream& os, std::string const& config,
  std::vector<std::string> const& evaluatedRPaths, Indent indent)
{
  os << indent << "if(NOT " << this->TmpVarPrefix
     << "_dep MATCHES \"\\\\.framework/\")\n";

  auto depName = cmStrCat(this->TmpVarPrefix, "_dep");
  this->AddInstallRule(
    os, this->GetDestination(config), cmInstallType_SHARED_LIBRARY, {}, false,
    this->Permissions.c_str(), nullptr, nullptr, " FOLLOW_SYMLINK_CHAIN",
    indent.Next(), depName.c_str());

  os << indent.Next() << "get_filename_component(" << this->TmpVarPrefix
     << "_dep_name \"${" << this->TmpVarPrefix << "_dep}\" NAME)\n";
  auto depNameVar = cmStrCat("${", this->TmpVarPrefix, "_dep_name}");
  this->GenerateInstallNameFixup(os, config, evaluatedRPaths,
                                 cmStrCat("${", this->TmpVarPrefix, "_dep}"),
                                 depNameVar, indent.Next());

  os << indent << "endif()\n";
}

void cmInstallRuntimeDependencySetGenerator::GenerateAppleFrameworkScript(
  std::ostream& os, std::string const& config,
  std::vector<std::string> const& evaluatedRPaths, Indent indent)
{
  os << indent << "if(" << this->TmpVarPrefix
     << "_dep MATCHES \"^(.*/)?([^/]*\\\\.framework)/(.*)$\")\n"
     << indent.Next() << "set(" << this->TmpVarPrefix
     << "_dir \"${CMAKE_MATCH_1}\")\n"
     << indent.Next() << "set(" << this->TmpVarPrefix
     << "_name \"${CMAKE_MATCH_2}\")\n"
     << indent.Next() << "set(" << this->TmpVarPrefix
     << "_file \"${CMAKE_MATCH_3}\")\n"
     << indent.Next() << "set(" << this->TmpVarPrefix << "_path \"${"
     << this->TmpVarPrefix << "_dir}${" << this->TmpVarPrefix << "_name}\")\n";

  auto depName = cmStrCat(this->TmpVarPrefix, "_path");
  this->AddInstallRule(
    os, this->GetDestination(config), cmInstallType_DIRECTORY, {}, false,
    this->Permissions.c_str(), nullptr, nullptr, " USE_SOURCE_PERMISSIONS",
    indent.Next(), depName.c_str());

  auto depNameVar = cmStrCat("${", this->TmpVarPrefix, "_name}/${",
                             this->TmpVarPrefix, "_file}");
  this->GenerateInstallNameFixup(os, config, evaluatedRPaths,
                                 cmStrCat("${", this->TmpVarPrefix, "_dep}"),
                                 depNameVar, indent.Next());

  os << indent << "endif()\n";
}

void cmInstallRuntimeDependencySetGenerator::GenerateInstallNameFixup(
  std::ostream& os, std::string const& config,
  std::vector<std::string> const& evaluatedRPaths, std::string const& filename,
  std::string const& depName, Indent indent)
{
  if (!(this->NoInstallRPath && this->NoInstallName)) {
    auto indent2 = indent;
    if (evaluatedRPaths.empty() && this->NoInstallName) {
      indent2 = indent2.Next();
      os << indent << "if(" << this->RPathPrefix << "_" << filename << ")\n";
    }
    os << indent2 << "set(" << this->TmpVarPrefix << "_rpath_args)\n";
    if (!this->NoInstallRPath) {
      os << indent2 << "foreach(" << this->TmpVarPrefix << "_rpath IN LISTS "
         << this->RPathPrefix << '_' << filename << ")\n"
         << indent2.Next() << "list(APPEND " << this->TmpVarPrefix
         << "_rpath_args -delete_rpath \"${" << this->TmpVarPrefix
         << "_rpath}\")\n"
         << indent2 << "endforeach()\n";
    }
    os << indent2 << "execute_process(COMMAND \""
       << this->LocalGenerator->GetMakefile()->GetSafeDefinition(
            "CMAKE_INSTALL_NAME_TOOL")
       << "\" ${" << this->TmpVarPrefix << "_rpath_args}\n";
    if (!this->NoInstallRPath) {
      for (auto const& rpath : evaluatedRPaths) {
        os << indent2 << "  -add_rpath " << cmScriptGenerator::Quote(rpath)
           << '\n';
      }
    }
    if (!this->NoInstallName) {
      os << indent2 << "  -id \"${" << this->TmpVarPrefix
         << "_install_name_dir}" << depName << "\"\n";
    }
    os << indent2 << "  \""
       << GetDestDirPath(
            ConvertToAbsoluteDestination(this->GetDestination(config)))
       << "/" << depName << "\")\n";
    if (evaluatedRPaths.empty() && this->NoInstallName) {
      os << indent << "endif()\n";
    }
  }
}

void cmInstallRuntimeDependencySetGenerator::GenerateStripFixup(
  std::ostream& os, std::string const& config, std::string const& depName,
  Indent indent)
{
  std::string strip =
    this->LocalGenerator->GetMakefile()->GetSafeDefinition("CMAKE_STRIP");
  if (!strip.empty()) {
    os << indent << "if(CMAKE_INSTALL_DO_STRIP)\n"
       << indent.Next() << "execute_process(COMMAND \"" << strip << "\" ";
    if (this->LocalGenerator->GetMakefile()->IsOn("APPLE")) {
      os << "-x ";
    }
    os << "\""
       << GetDestDirPath(
            ConvertToAbsoluteDestination(this->GetDestination(config)))
       << "/" << depName << "\")\n"
       << indent << "endif()\n";
  }
}

std::string cmInstallRuntimeDependencySetGenerator::GetDestination(
  std::string const& config) const
{
  return cmGeneratorExpression::Evaluate(this->Destination,
                                         this->LocalGenerator, config);
}
