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

#include <map>
#include <sstream>
#include <utility>

#include "cmCryptoHash.h"
#include "cmDiagnosticContext.h"
#include "cmExportInstallFileGenerator.h"
#include "cmExportSet.h"
#include "cmInstallType.h"
#include "cmLocalGenerator.h"
#include "cmScriptGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

cmInstallExportGenerator::cmInstallExportGenerator(
  cmExportSet* exportSet, std::string destination, std::string filePermissions,
  std::vector<std::string> const& configurations, std::string component,
  MessageLevel message, bool excludeFromAll, std::string filename,
  std::string targetNamespace, std::string cxxModulesDirectory,
  cmDiagnosticContext context)
  : cmInstallGenerator(std::move(destination), configurations,
                       std::move(component), message, excludeFromAll, false,
                       std::move(context))
  , ExportSet(exportSet)
  , FilePermissions(std::move(filePermissions))
  , FileName(std::move(filename))
  , Namespace(std::move(targetNamespace))
  , CxxModulesDirectory(std::move(cxxModulesDirectory))
{
  exportSet->AddInstallation(this);
}

cmInstallExportGenerator::~cmInstallExportGenerator() = default;

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

std::string cmInstallExportGenerator::TempDirCalculate() const
{
  // Choose a temporary directory in which to generate the import
  // files to be installed.
  std::string path = cmStrCat(
    this->LocalGenerator->GetCurrentBinaryDirectory(), "/CMakeFiles/Export");
  if (this->Destination.empty()) {
    return path;
  }

  cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
  path += '/';
  // Replace the destination path with a hash to keep it short.
  path += hasher.HashString(this->Destination);

  return path;
}

void cmInstallExportGenerator::ComputeTempDir()
{
  this->TempDir = this->TempDirCalculate();
}

std::string cmInstallExportGenerator::GetTempDir() const
{
  if (this->TempDir.empty()) {
    return this->TempDirCalculate();
  }
  return this->TempDir;
}

void cmInstallExportGenerator::GenerateScript(std::ostream& os)
{
  // Skip empty sets.
  if (this->ExportSet->GetTargetExports().empty()) {
    std::ostringstream e;
    e << "INSTALL(" << this->InstallSubcommand() << ") given unknown export \""
      << this->ExportSet->GetName() << "\"";
    cmSystemTools::Error(e.str());
    return;
  }

  // Create the temporary directory in which to store the files.
  this->ComputeTempDir();
  cmSystemTools::MakeDirectory(this->TempDir);

  // Construct a temporary location for the file.
  this->MainImportFile = cmStrCat(this->TempDir, '/', this->FileName);

  // Generate the import file for this export set.
  this->EFGen->SetExportFile(this->MainImportFile.c_str());
  this->EFGen->SetNamespace(this->Namespace);
  if (this->ConfigurationTypes->empty()) {
    if (!this->ConfigurationName.empty()) {
      this->EFGen->AddConfiguration(this->ConfigurationName);
    } else {
      this->EFGen->AddConfiguration("");
    }
  } else {
    for (std::string const& c : *this->ConfigurationTypes) {
      this->EFGen->AddConfiguration(c);
    }
  }
  this->EFGen->GenerateImportFile();

  // Perform the main install script generation.
  this->cmInstallGenerator::GenerateScript(os);
}

void cmInstallExportGenerator::GenerateScriptConfigs(std::ostream& os,
                                                     Indent indent)
{
  // Create the main install rules first.
  this->cmInstallGenerator::GenerateScriptConfigs(os, indent);

  // Now create a configuration-specific install rule for the import
  // file of each configuration.
  std::vector<std::string> files;
  for (auto const& i : this->EFGen->GetConfigImportFiles()) {
    files.push_back(i.second);
    std::string configTest = this->CreateConfigTest(i.first);
    os << indent << "if(" << configTest << ")\n";
    this->AddInstallRule(os, this->Destination, cmInstallType_FILES, files,
                         false, this->FilePermissions.c_str(), nullptr,
                         nullptr, nullptr, indent.Next());
    os << indent << "endif()\n";
    files.clear();
  }

  // Now create a configuration-specific install rule for the C++ module import
  // property file of each configuration.
  auto const cxxModuleDestination =
    cmStrCat(this->Destination, '/', this->CxxModulesDirectory);
  auto const cxxModuleInstallFilePath = this->EFGen->GetCxxModuleFile();
  auto const configImportFilesGlob = this->EFGen->GetConfigImportFileGlob();
  if (!cxxModuleInstallFilePath.empty() && !configImportFilesGlob.empty()) {
    auto const cxxModuleFilename =
      cmSystemTools::GetFilenameName(cxxModuleInstallFilePath);

    // Remove old per-configuration export files if the main changes.
    std::string installedDir =
      cmStrCat("$ENV{DESTDIR}",
               ConvertToAbsoluteDestination(cxxModuleDestination), '/');
    std::string installedFile = cmStrCat(installedDir, cxxModuleFilename);
    os << indent << "if(EXISTS \"" << installedFile << "\")\n";
    Indent indentN = indent.Next();
    Indent indentNN = indentN.Next();
    Indent indentNNN = indentNN.Next();
    os << indentN << "file(DIFFERENT _cmake_export_file_changed FILES\n"
       << indentN << "     \"" << installedFile << "\"\n"
       << indentN << "     \"" << cxxModuleInstallFilePath << "\")\n";
    os << indentN << "if(_cmake_export_file_changed)\n";
    os << indentNN << "file(GLOB _cmake_old_config_files \"" << installedDir
       << configImportFilesGlob << "\")\n";
    os << indentNN << "if(_cmake_old_config_files)\n";
    os << indentNNN
       << "string(REPLACE \";\" \", \" _cmake_old_config_files_text "
          "\"${_cmake_old_config_files}\")\n";
    os << indentNNN << R"(message(STATUS "Old C++ module export file \")"
       << installedFile
       << "\\\" will be replaced.  "
          "Removing files [${_cmake_old_config_files_text}].\")\n";
    os << indentNNN << "unset(_cmake_old_config_files_text)\n";
    os << indentNNN << "file(REMOVE ${_cmake_old_config_files})\n";
    os << indentNN << "endif()\n";
    os << indentNN << "unset(_cmake_old_config_files)\n";
    os << indentN << "endif()\n";
    os << indentN << "unset(_cmake_export_file_changed)\n";
    os << indent << "endif()\n";

    // All of these files are siblings; get its location to know where the
    // "anchor" file is.
    files.push_back(cxxModuleInstallFilePath);
    this->AddInstallRule(os, cxxModuleDestination, cmInstallType_FILES, files,
                         false, this->FilePermissions.c_str(), nullptr,
                         nullptr, nullptr, indent);
    files.clear();
  }
  for (auto const& i : this->EFGen->GetConfigCxxModuleFiles()) {
    files.push_back(i.second);
    std::string configTest = this->CreateConfigTest(i.first);
    os << indent << "if(" << configTest << ")\n";
    this->AddInstallRule(os, cxxModuleDestination, cmInstallType_FILES, files,
                         false, this->FilePermissions.c_str(), nullptr,
                         nullptr, nullptr, indent.Next());
    os << indent << "endif()\n";
    files.clear();
  }
  for (auto const& i : this->EFGen->GetConfigCxxModuleTargetFiles()) {
    std::string configTest = this->CreateConfigTest(i.first);
    os << indent << "if(" << configTest << ")\n";
    this->AddInstallRule(os, cxxModuleDestination, cmInstallType_FILES,
                         i.second, false, this->FilePermissions.c_str(),
                         nullptr, nullptr, nullptr, indent.Next());
    os << indent << "endif()\n";
    files.clear();
  }
}

void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os,
                                                     Indent indent)
{
  auto const configImportFilesGlob = this->EFGen->GetConfigImportFileGlob();
  if (!configImportFilesGlob.empty()) {
    // Remove old per-configuration export files if the main changes.
    std::string installedDir = cmStrCat(
      "$ENV{DESTDIR}", ConvertToAbsoluteDestination(this->Destination), '/');
    std::string installedFile = cmStrCat(installedDir, this->FileName);
    os << indent << "if(EXISTS \"" << installedFile << "\")\n";
    Indent indentN = indent.Next();
    Indent indentNN = indentN.Next();
    Indent indentNNN = indentNN.Next();
    os << indentN << "file(DIFFERENT _cmake_export_file_changed FILES\n"
       << indentN << "     \"" << installedFile << "\"\n"
       << indentN << "     \"" << this->MainImportFile << "\")\n";
    os << indentN << "if(_cmake_export_file_changed)\n";
    os << indentNN << "file(GLOB _cmake_old_config_files \"" << installedDir
       << configImportFilesGlob << "\")\n";
    os << indentNN << "if(_cmake_old_config_files)\n";
    os << indentNNN
       << "string(REPLACE \";\" \", \" _cmake_old_config_files_text "
          "\"${_cmake_old_config_files}\")\n";
    os << indentNNN << R"(message(STATUS "Old export file \")" << installedFile
       << "\\\" will be replaced.  "
          "Removing files [${_cmake_old_config_files_text}].\")\n";
    os << indentNNN << "unset(_cmake_old_config_files_text)\n";
    os << indentNNN << "file(REMOVE ${_cmake_old_config_files})\n";
    os << indentNN << "endif()\n";
    os << indentNN << "unset(_cmake_old_config_files)\n";
    os << indentN << "endif()\n";
    os << indentN << "unset(_cmake_export_file_changed)\n";
    os << indent << "endif()\n";
  }

  // Install the main export file.
  std::vector<std::string> files;
  files.push_back(this->MainImportFile);
  this->AddInstallRule(os, this->Destination, cmInstallType_FILES, files,
                       false, this->FilePermissions.c_str(), nullptr, nullptr,
                       nullptr, indent);
}

std::string cmInstallExportGenerator::GetDestinationFile() const
{
  return cmStrCat(this->Destination, '/', this->FileName);
}
