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

#include <cstddef>
#include <functional>
#include <map>
#include <ostream>
#include <set>
#include <utility>
#include <vector>

#include "cmCryptoHash.h"
#include "cmDiagnosticContext.h"
#include "cmExportSet.h"
#include "cmGenExContext.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetTypes.h"

cmExportBuildCMakeConfigGenerator::cmExportBuildCMakeConfigGenerator(
  cmDiagnosticContext context)
  : cmExportBuildFileGenerator(std::move(context))
{
  this->LG = nullptr;
  this->ExportSet = nullptr;
}

bool cmExportBuildCMakeConfigGenerator::GenerateMainFile(std::ostream& os)
{
  {
    std::string expectedTargets;
    std::string sep;
    bool generatedInterfaceRequired = false;
    auto visitor = [&](cmGeneratorTarget const* te) {
      expectedTargets += sep + this->Namespace + te->GetExportName();
      sep = " ";

      generatedInterfaceRequired |=
        this->GetExportTargetType(te) == cm::TargetType::INTERFACE_LIBRARY;
    };

    if (!this->CollectExports(visitor)) {
      return false;
    }

    if (generatedInterfaceRequired) {
      this->SetRequiredCMakeVersion(3, 0, 0);
    }
    this->GenerateExpectedTargetsCode(os, expectedTargets);
  }

  // Create all the imported targets.
  for (auto const& exp : this->Exports) {
    cmGeneratorTarget* gte = exp.Target;
    this->GenerateImportTargetCode(os, gte, this->GetExportTargetType(gte));

    gte->Target->AppendBuildInterfaceIncludes();

    ImportPropertyMap properties;
    if (!this->PopulateInterfaceProperties(gte, properties)) {
      return false;
    }

    ImportFileSetPropertyMap fsProperties;
    if (!this->PopulateFileSetInterfaceProperties(gte, fsProperties)) {
      return false;
    }

    this->PopulateInterfaceLinkLibrariesProperty(
      gte, cmGeneratorExpression::BuildInterface, properties);

    this->GenerateInterfaceProperties(gte, os, properties);

    this->GenerateTargetFileSets(gte, os, fsProperties);
  }

  std::string cxx_modules_name;
  if (this->ExportSet) {
    cxx_modules_name = this->ExportSet->GetName();
  } else {
    cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
    constexpr std::size_t HASH_TRUNCATION = 12;
    for (auto const& target : this->Targets) {
      hasher.Append(target.Name);
    }
    cxx_modules_name = hasher.FinalizeHex().substr(0, HASH_TRUNCATION);
  }

  this->GenerateCxxModuleInformation(cxx_modules_name, os);

  // Generate import file content for each configuration.
  for (std::string const& c : this->Configurations) {
    this->GenerateImportConfig(os, c);
  }

  // Generate import file content for each configuration.
  for (std::string const& c : this->Configurations) {
    this->GenerateImportCxxModuleConfigTargetInclusion(cxx_modules_name, c);
  }

  this->GenerateMissingTargetsCheckCode(os);

  return true;
}

void cmExportBuildCMakeConfigGenerator::GenerateImportTargetsConfig(
  std::ostream& os, std::string const& config, std::string const& suffix)
{
  for (auto const& exp : this->Exports) {
    cmGeneratorTarget* target = exp.Target;

    // Collect import properties for this target.
    ImportPropertyMap properties;

    if (this->GetExportTargetType(target) !=
        cm::TargetType::INTERFACE_LIBRARY) {
      this->SetImportLocationProperty(config, suffix, target, properties);
    }
    if (!properties.empty()) {
      // Get the rest of the target details.
      if (this->GetExportTargetType(target) !=
          cm::TargetType::INTERFACE_LIBRARY) {
        this->SetImportDetailProperties(config, suffix, target, properties);
        this->SetImportLinkInterface(config, suffix,
                                     cmGeneratorExpression::BuildInterface,
                                     target, properties);
      }

      // TODO: PUBLIC_HEADER_LOCATION
      // This should wait until the build feature propagation stuff
      // is done.  Then this can be a propagated include directory.
      // this->GenerateImportProperty(config, te->HeaderGenerator,
      //                              properties);

      // Generate code in the export file.
      std::string importedXcFrameworkLocation = exp.XcFrameworkLocation;
      if (!importedXcFrameworkLocation.empty()) {
        importedXcFrameworkLocation = cmGeneratorExpression::Preprocess(
          importedXcFrameworkLocation,
          cmGeneratorExpression::PreprocessContext::BuildInterface);
        importedXcFrameworkLocation = cmGeneratorExpression::Evaluate(
          importedXcFrameworkLocation, exp.Target->GetLocalGenerator(), config,
          exp.Target, nullptr, exp.Target);
        if (!importedXcFrameworkLocation.empty() &&
            !cmSystemTools::FileIsFullPath(importedXcFrameworkLocation)) {
          importedXcFrameworkLocation =
            cmStrCat(this->LG->GetCurrentBinaryDirectory(), '/',
                     importedXcFrameworkLocation);
        }
      }
      this->GenerateImportPropertyCode(os, config, suffix, target, properties,
                                       importedXcFrameworkLocation);
    }
  }
}

std::string cmExportBuildCMakeConfigGenerator::GetFileSetDirectories(
  cmGeneratorTarget* gte, cmGeneratorFileSet const* fileSet,
  cmTargetExport const* /*te*/)
{
  std::vector<std::string> resultVector;

  auto configs =
    gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);

  for (auto const& config : configs) {
    cm::GenEx::Context context(gte->LocalGenerator, config);
    auto directories = fileSet->GetDirectories(context, gte);
    bool const contextSensitive = directories.second;

    for (auto const& directory : directories.first) {
      auto dest = cmOutputConverter::EscapeForCMake(
        directory, cmOutputConverter::WrapQuotes::NoWrap);

      if (contextSensitive && configs.size() != 1) {
        resultVector.push_back(
          cmStrCat("\"$<$<CONFIG:", config, ">:", dest, ">\""));
      } else {
        resultVector.emplace_back(cmStrCat('"', dest, '"'));
      }
    }
  }

  return cmJoin(resultVector, " ");
}

std::string cmExportBuildCMakeConfigGenerator::GetFileSetFiles(
  cmGeneratorTarget* gte, cmGeneratorFileSet const* fileSet,
  cmTargetExport const* /*te*/)
{
  std::vector<std::string> resultVector;

  auto configs =
    gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);

  for (auto const& config : configs) {
    cm::GenEx::Context context(gte->LocalGenerator, config);

    auto files = fileSet->GetFiles(context, gte);
    bool const contextSensitive = files.second;

    for (auto const& it : files.first) {
      for (auto const& filename : it.second) {
        auto escapedFile = cmOutputConverter::EscapeForCMake(
          filename, cmOutputConverter::WrapQuotes::NoWrap);
        if (contextSensitive && configs.size() != 1) {
          resultVector.push_back(
            cmStrCat("\"$<$<CONFIG:", config, ">:", escapedFile, ">\""));
        } else {
          resultVector.emplace_back(cmStrCat('"', escapedFile, '"'));
        }
      }
    }

    if (!(contextSensitive && configs.size() != 1)) {
      break;
    }
  }

  return cmJoin(resultVector, " ");
}

void cmExportBuildCMakeConfigGenerator::GenerateCxxModuleConfigInformation(
  std::string const& name, std::ostream& os) const
{
  char const* opt = "";
  if (this->Configurations.size() > 1) {
    // With more than one configuration, each individual file is optional.
    opt = " OPTIONAL";
  }

  // Generate import file content for each configuration.
  for (std::string c : this->Configurations) {
    if (c.empty()) {
      c = "noconfig";
    }
    os << "include(\"${CMAKE_CURRENT_LIST_DIR}/cxx-modules-" << name << '-'
       << c << ".cmake\"" << opt << ")\n";
  }
}

bool cmExportBuildCMakeConfigGenerator::
  GenerateImportCxxModuleConfigTargetInclusion(std::string const& name,
                                               std::string config) const
{
  auto cxx_modules_dirname = this->GetCxxModulesDirectory();
  if (cxx_modules_dirname.empty()) {
    return true;
  }

  if (config.empty()) {
    config = "noconfig";
  }

  std::string fileName =
    cmStrCat(this->FileDir, '/', cxx_modules_dirname, "/cxx-modules-", name,
             '-', config, ".cmake");

  cmGeneratedFileStream os(fileName, true);
  if (!os) {
    std::string se = cmSystemTools::GetLastSystemError();
    cmSystemTools::Error(
      cmStrCat("cannot write to file \"", fileName, "\": ", se));
    return false;
  }
  os.SetCopyIfDifferent(true);

  for (auto const* tgt : this->ExportedTargets) {
    // Only targets with C++ module sources will have a
    // collator-generated install script.
    if (!tgt->HaveCxx20ModuleSources()) {
      continue;
    }

    os << "include(\"${CMAKE_CURRENT_LIST_DIR}/target-"
       << tgt->GetFilesystemExportName() << '-' << config << ".cmake\")\n";
  }

  return true;
}
