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

#include <algorithm>
#include <cassert>
#include <sstream>
#include <utility>
#include <vector>

#include <cm/optional>
#include <cm/string_view>
#include <cmext/string_view>

#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmFindPackageStack.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmValue.h"
#include "cmVersion.h"

static std::string cmExportFileGeneratorEscape(std::string const& str)
{
  // Escape a property value for writing into a .cmake file.
  std::string result = cmOutputConverter::EscapeForCMake(str);
  // Un-escape variable references generated by our own export code.
  cmSystemTools::ReplaceString(result, "\\${_IMPORT_PREFIX}",
                               "${_IMPORT_PREFIX}");
  cmSystemTools::ReplaceString(result, "\\${CMAKE_IMPORT_LIBRARY_SUFFIX}",
                               "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
  return result;
}

cmExportCMakeConfigGenerator::cmExportCMakeConfigGenerator() = default;

cm::string_view cmExportCMakeConfigGenerator::GetImportPrefixWithSlash() const
{
  return "${_IMPORT_PREFIX}/"_s;
}

bool cmExportCMakeConfigGenerator::GenerateImportFile(std::ostream& os)
{
  std::stringstream mainFileWithHeadersAndFootersBuffer;

  // Start with the import file header.
  this->GenerateImportHeaderCode(mainFileWithHeadersAndFootersBuffer);

  // Create all the imported targets.
  std::stringstream mainFileBuffer;
  bool result = this->GenerateMainFile(mainFileBuffer);

  // Export find_dependency() calls. Must be done after GenerateMainFile(),
  // because that's when target dependencies are gathered, which we need for
  // the find_dependency() calls.
  if (!this->AppendMode && this->GetExportSet() &&
      this->ExportPackageDependencies) {
    this->SetRequiredCMakeVersion(3, 9, 0);
    this->GenerateFindDependencyCalls(mainFileWithHeadersAndFootersBuffer);
  }

  // Write cached import code.
  mainFileWithHeadersAndFootersBuffer << mainFileBuffer.rdbuf();

  // End with the import file footer.
  this->GenerateImportFooterCode(mainFileWithHeadersAndFootersBuffer);
  this->GeneratePolicyFooterCode(mainFileWithHeadersAndFootersBuffer);

  // This has to be done last, after the minimum CMake version has been
  // determined.
  this->GeneratePolicyHeaderCode(os);
  os << mainFileWithHeadersAndFootersBuffer.rdbuf();

  return result;
}

void cmExportCMakeConfigGenerator::GenerateInterfaceProperties(
  cmGeneratorTarget const* target, std::ostream& os,
  ImportPropertyMap const& properties)
{
  if (!properties.empty()) {
    std::string targetName =
      cmStrCat(this->Namespace, target->GetExportName());
    os << "set_target_properties(" << targetName << " PROPERTIES\n";
    for (auto const& property : properties) {
      os << "  " << property.first << " "
         << cmExportFileGeneratorEscape(property.second) << "\n";
    }
    os << ")\n\n";
  }
}

void cmExportCMakeConfigGenerator::SetImportLinkInterface(
  std::string const& config, std::string const& suffix,
  cmGeneratorExpression::PreprocessContext preprocessRule,
  cmGeneratorTarget const* target, ImportPropertyMap& properties)
{
  // Add the transitive link dependencies for this configuration.
  cmLinkInterface const* iface = target->GetLinkInterface(config, target);
  if (!iface) {
    return;
  }

  if (iface->ImplementationIsInterface) {
    // Policy CMP0022 must not be NEW.
    this->SetImportLinkProperty(
      suffix, target, "IMPORTED_LINK_INTERFACE_LIBRARIES", iface->Libraries,
      properties, ImportLinkPropertyTargetNames::Yes);
    return;
  }

  cmValue propContent;

  if (cmValue prop_suffixed =
        target->GetProperty("LINK_INTERFACE_LIBRARIES" + suffix)) {
    propContent = prop_suffixed;
  } else if (cmValue prop = target->GetProperty("LINK_INTERFACE_LIBRARIES")) {
    propContent = prop;
  } else {
    return;
  }

  bool const newCMP0022Behavior =
    target->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
    target->GetPolicyStatusCMP0022() != cmPolicies::OLD;

  if (newCMP0022Behavior && !this->ExportOld) {
    cmLocalGenerator* lg = target->GetLocalGenerator();
    std::ostringstream e;
    e << "Target \"" << target->GetName()
      << "\" has policy CMP0022 enabled, "
         "but also has old-style LINK_INTERFACE_LIBRARIES properties "
         "populated, but it was exported without the "
         "EXPORT_LINK_INTERFACE_LIBRARIES to export the old-style properties";
    lg->IssueMessage(MessageType::FATAL_ERROR, e.str());
    return;
  }

  if (propContent->empty()) {
    properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix].clear();
    return;
  }

  std::string prepro =
    cmGeneratorExpression::Preprocess(*propContent, preprocessRule);
  if (!prepro.empty()) {
    this->ResolveTargetsInGeneratorExpressions(prepro, target,
                                               ReplaceFreeTargets);
    properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro;
  }
}

void cmExportCMakeConfigGenerator::GeneratePolicyHeaderCode(std::ostream& os)
{
  // Protect that file against use with older CMake versions.
  /* clang-format off */
  os << "# Generated by CMake\n\n";
  os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.8)\n"
     << "   message(FATAL_ERROR \"CMake >= "
     << this->RequiredCMakeVersionMajor << '.'
     << this->RequiredCMakeVersionMinor << '.'
     << this->RequiredCMakeVersionPatch << " required\")\n"
     << "endif()\n"
     << "if(CMAKE_VERSION VERSION_LESS \""
     << this->RequiredCMakeVersionMajor << '.'
     << this->RequiredCMakeVersionMinor << '.'
     << this->RequiredCMakeVersionPatch << "\")\n"
     << "   message(FATAL_ERROR \"CMake >= "
     << this->RequiredCMakeVersionMajor << '.'
     << this->RequiredCMakeVersionMinor << '.'
     << this->RequiredCMakeVersionPatch << " required\")\n"
     << "endif()\n";
  /* clang-format on */

  // Isolate the file policy level.
  // Support CMake versions as far back as the
  // RequiredCMakeVersion{Major,Minor,Patch}, but also support using NEW
  // policy settings for up to CMake 3.30 (this upper limit may be reviewed
  // and increased from time to time). This reduces the opportunity for CMake
  // warnings when an older export file is later used with newer CMake
  // versions.
  /* clang-format off */
  os << "cmake_policy(PUSH)\n"
     << "cmake_policy(VERSION "
     << this->RequiredCMakeVersionMajor << '.'
     << this->RequiredCMakeVersionMinor << '.'
     << this->RequiredCMakeVersionPatch << "...3.30)\n";
  /* clang-format on */
}

void cmExportCMakeConfigGenerator::GeneratePolicyFooterCode(std::ostream& os)
{
  os << "cmake_policy(POP)\n";
}

void cmExportCMakeConfigGenerator::GenerateImportHeaderCode(
  std::ostream& os, std::string const& config)
{
  os << "#----------------------------------------------------------------\n"
     << "# Generated CMake target import file";
  if (!config.empty()) {
    os << " for configuration \"" << config << "\".\n";
  } else {
    os << ".\n";
  }
  os << "#----------------------------------------------------------------\n"
     << "\n";
  this->GenerateImportVersionCode(os);
}

void cmExportCMakeConfigGenerator::GenerateImportFooterCode(std::ostream& os)
{
  os << "# Commands beyond this point should not need to know the version.\n"
     << "set(CMAKE_IMPORT_FILE_VERSION)\n";
}

void cmExportCMakeConfigGenerator::GenerateImportVersionCode(std::ostream& os)
{
  // Store an import file format version.  This will let us change the
  // format later while still allowing old import files to work.
  /* clang-format off */
  os << "# Commands may need to know the format version.\n"
     << "set(CMAKE_IMPORT_FILE_VERSION 1)\n"
     << "\n";
  /* clang-format on */
}

void cmExportCMakeConfigGenerator::GenerateExpectedTargetsCode(
  std::ostream& os, std::string const& expectedTargets)
{
  /* clang-format off */
  os << "# Protect against multiple inclusion, which would fail when already "
        "imported targets are added once more.\n"
        "set(_cmake_targets_defined \"\")\n"
        "set(_cmake_targets_not_defined \"\")\n"
        "set(_cmake_expected_targets \"\")\n"
        "foreach(_cmake_expected_target IN ITEMS " << expectedTargets << ")\n"
        "  list(APPEND _cmake_expected_targets \"${_cmake_expected_target}\")\n"
        "  if(TARGET \"${_cmake_expected_target}\")\n"
        "    list(APPEND _cmake_targets_defined \"${_cmake_expected_target}\")\n"
        "  else()\n"
        "    list(APPEND _cmake_targets_not_defined \"${_cmake_expected_target}\")\n"
        "  endif()\n"
        "endforeach()\n"
        "unset(_cmake_expected_target)\n"
        "if(_cmake_targets_defined STREQUAL _cmake_expected_targets)\n"
        "  unset(_cmake_targets_defined)\n"
        "  unset(_cmake_targets_not_defined)\n"
        "  unset(_cmake_expected_targets)\n"
        "  unset(CMAKE_IMPORT_FILE_VERSION)\n"
        "  cmake_policy(POP)\n"
        "  return()\n"
        "endif()\n"
        "if(NOT _cmake_targets_defined STREQUAL \"\")\n"
        "  string(REPLACE \";\" \", \" _cmake_targets_defined_text \"${_cmake_targets_defined}\")\n"
        "  string(REPLACE \";\" \", \" _cmake_targets_not_defined_text \"${_cmake_targets_not_defined}\")\n"
        "  message(FATAL_ERROR \"Some (but not all) targets in this export "
        "set were already defined.\\nTargets Defined: ${_cmake_targets_defined_text}\\n"
        "Targets not yet defined: ${_cmake_targets_not_defined_text}\\n\")\n"
        "endif()\n"
        "unset(_cmake_targets_defined)\n"
        "unset(_cmake_targets_not_defined)\n"
        "unset(_cmake_expected_targets)\n"
        "\n\n";
  /* clang-format on */
}

void cmExportCMakeConfigGenerator::GenerateImportTargetCode(
  std::ostream& os, cmGeneratorTarget const* target,
  cmStateEnums::TargetType targetType)
{
  // Construct the imported target name.
  std::string targetName = this->Namespace;

  targetName += target->GetExportName();

  // Create the imported target.
  os << "# Create imported target " << targetName << "\n";
  switch (targetType) {
    case cmStateEnums::EXECUTABLE:
      os << "add_executable(" << targetName << " IMPORTED)\n";
      break;
    case cmStateEnums::STATIC_LIBRARY:
      os << "add_library(" << targetName << " STATIC IMPORTED)\n";
      break;
    case cmStateEnums::SHARED_LIBRARY:
      os << "add_library(" << targetName << " SHARED IMPORTED)\n";
      break;
    case cmStateEnums::MODULE_LIBRARY:
      os << "add_library(" << targetName << " MODULE IMPORTED)\n";
      break;
    case cmStateEnums::UNKNOWN_LIBRARY:
      os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n";
      break;
    case cmStateEnums::OBJECT_LIBRARY:
      os << "add_library(" << targetName << " OBJECT IMPORTED)\n";
      break;
    case cmStateEnums::INTERFACE_LIBRARY:
      os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
      break;
    default: // should never happen
      break;
  }

  // Mark the imported executable if it has exports.
  if (target->IsExecutableWithExports() ||
      (target->IsSharedLibraryWithExports() && target->HasImportLibrary(""))) {
    os << "set_property(TARGET " << targetName
       << " PROPERTY ENABLE_EXPORTS 1)\n";
  }

  // Mark the imported library if it is a framework.
  if (target->IsFrameworkOnApple()) {
    os << "set_property(TARGET " << targetName << " PROPERTY FRAMEWORK 1)\n";
  }

  // Mark the imported executable if it is an application bundle.
  if (target->IsAppBundleOnApple()) {
    os << "set_property(TARGET " << targetName
       << " PROPERTY MACOSX_BUNDLE 1)\n";
  }

  if (target->IsCFBundleOnApple()) {
    os << "set_property(TARGET " << targetName << " PROPERTY BUNDLE 1)\n";
  }

  // generate DEPRECATION
  if (target->IsDeprecated()) {
    os << "set_property(TARGET " << targetName << " PROPERTY DEPRECATION "
       << cmExportFileGeneratorEscape(target->GetDeprecation()) << ")\n";
  }

  if (target->GetPropertyAsBool("IMPORTED_NO_SYSTEM")) {
    os << "set_property(TARGET " << targetName
       << " PROPERTY IMPORTED_NO_SYSTEM 1)\n";
  }

  if (target->GetPropertyAsBool("EXPORT_NO_SYSTEM")) {
    os << "set_property(TARGET " << targetName << " PROPERTY SYSTEM 0)\n";
  }

  os << "\n";
}

void cmExportCMakeConfigGenerator::GenerateImportPropertyCode(
  std::ostream& os, std::string const& config, std::string const& suffix,
  cmGeneratorTarget const* target, ImportPropertyMap const& properties,
  std::string const& importedXcFrameworkLocation)
{
  // Construct the imported target name.
  std::string targetName = this->Namespace;

  targetName += target->GetExportName();

  // Set the import properties.
  os << "# Import target \"" << targetName << "\" for configuration \""
     << config << "\"\n";
  os << "set_property(TARGET " << targetName
     << " APPEND PROPERTY IMPORTED_CONFIGURATIONS ";
  if (!config.empty()) {
    os << cmSystemTools::UpperCase(config);
  } else {
    os << "NOCONFIG";
  }
  os << ")\n";
  os << "set_target_properties(" << targetName << " PROPERTIES\n";
  std::string importedLocationProp = cmStrCat("IMPORTED_LOCATION", suffix);
  for (auto const& property : properties) {
    if (importedXcFrameworkLocation.empty() ||
        property.first != importedLocationProp) {
      os << "  " << property.first << " "
         << cmExportFileGeneratorEscape(property.second) << "\n";
    }
  }
  os << "  )\n";
  if (!importedXcFrameworkLocation.empty()) {
    auto importedLocationIt = properties.find(importedLocationProp);
    if (importedLocationIt != properties.end()) {
      os << "if(NOT CMAKE_VERSION VERSION_LESS \"3.28\" AND IS_DIRECTORY "
         << cmExportFileGeneratorEscape(importedXcFrameworkLocation)
         << ")\n"
            "  set_property(TARGET "
         << targetName << " PROPERTY " << importedLocationProp << " "
         << cmExportFileGeneratorEscape(importedXcFrameworkLocation)
         << ")\nelse()\n  set_property(TARGET " << targetName << " PROPERTY "
         << importedLocationProp << " "
         << cmExportFileGeneratorEscape(importedLocationIt->second)
         << ")\nendif()\n";
    }
  }
  os << "\n";
}

void cmExportCMakeConfigGenerator::GenerateFindDependencyCalls(
  std::ostream& os)
{
  os << "include(CMakeFindDependencyMacro)\n";
  std::map<std::string, cmExportSet::PackageDependency> packageDependencies;
  auto* exportSet = this->GetExportSet();
  if (exportSet) {
    packageDependencies = exportSet->GetPackageDependencies();
  }

  for (cmGeneratorTarget const* gt : this->ExternalTargets) {
    std::string findPackageName;
    auto exportFindPackageName = gt->GetProperty("EXPORT_FIND_PACKAGE_NAME");
    cmFindPackageStack pkgStack = gt->Target->GetFindPackageStack();
    if (!exportFindPackageName.IsEmpty()) {
      findPackageName = *exportFindPackageName;
    } else {
      if (!pkgStack.Empty()) {
        cmFindPackageCall const& fpc = pkgStack.Top();
        findPackageName = fpc.Name;
      }
    }
    if (!findPackageName.empty()) {
      auto& dep = packageDependencies[findPackageName];
      if (!pkgStack.Empty()) {
        dep.FindPackageIndex = pkgStack.Top().Index;
      }
      if (dep.Enabled == cmExportSet::PackageDependencyExportEnabled::Auto) {
        dep.Enabled = cmExportSet::PackageDependencyExportEnabled::On;
      }
    }
  }

  std::vector<std::pair<std::string, cmExportSet::PackageDependency>>
    packageDependenciesSorted(packageDependencies.begin(),
                              packageDependencies.end());
  std::sort(
    packageDependenciesSorted.begin(), packageDependenciesSorted.end(),
    [](std::pair<std::string, cmExportSet::PackageDependency> const& lhs,
       std::pair<std::string, cmExportSet::PackageDependency> const& rhs)
      -> bool {
      if (lhs.second.SpecifiedIndex) {
        if (rhs.second.SpecifiedIndex) {
          return lhs.second.SpecifiedIndex < rhs.second.SpecifiedIndex;
        }
        assert(rhs.second.FindPackageIndex);
        return true;
      }
      assert(lhs.second.FindPackageIndex);
      if (rhs.second.SpecifiedIndex) {
        return false;
      }
      assert(rhs.second.FindPackageIndex);
      return lhs.second.FindPackageIndex < rhs.second.FindPackageIndex;
    });

  for (auto const& it : packageDependenciesSorted) {
    if (it.second.Enabled == cmExportSet::PackageDependencyExportEnabled::On) {
      os << "find_dependency(" << it.first;
      for (auto const& arg : it.second.ExtraArguments) {
        os << " " << cmOutputConverter::EscapeForCMake(arg);
      }
      os << ")\n";
    }
  }
  os << "\n\n";
}

void cmExportCMakeConfigGenerator::GenerateMissingTargetsCheckCode(
  std::ostream& os)
{
  if (this->MissingTargets.empty()) {
    /* clang-format off */
    os << "# This file does not depend on other imported targets which have\n"
          "# been exported from the same project but in a separate "
            "export set.\n\n";
    /* clang-format on */
    return;
  }
  /* clang-format off */
  os << "# Make sure the targets which have been exported in some other\n"
        "# export set exist.\n"
        "unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n"
        "foreach(_target ";
  /* clang-format on */
  std::set<std::string> emitted;
  for (std::string const& missingTarget : this->MissingTargets) {
    if (emitted.insert(missingTarget).second) {
      os << "\"" << missingTarget << "\" ";
    }
  }
  /* clang-format off */
  os << ")\n"
        "  if(NOT TARGET \"${_target}\" )\n"
        "    set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets \""
        "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets} ${_target}\")"
        "\n"
        "  endif()\n"
        "endforeach()\n"
        "\n"
        "if(DEFINED ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n"
        "  if(CMAKE_FIND_PACKAGE_NAME)\n"
        "    set( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n"
        "    set( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "
        "\"The following imported targets are "
        "referenced, but are missing: "
                 "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets}\")\n"
        "  else()\n"
        "    message(FATAL_ERROR \"The following imported targets are "
        "referenced, but are missing: "
                "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets}\")\n"
        "  endif()\n"
        "endif()\n"
        "unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n"
        "\n";
  /* clang-format on */
}

void cmExportCMakeConfigGenerator::GenerateImportedFileCheckLoop(
  std::ostream& os)
{
  // Add code which verifies at cmake time that the file which is being
  // imported actually exists on disk. This should in theory always be theory
  // case, but still when packages are split into normal and development
  // packages this might get broken (e.g. the Config.cmake could be part of
  // the non-development package, something similar happened to me without
  // on SUSE with a mysql pkg-config file, which claimed everything is fine,
  // but the development package was not installed.).
  /* clang-format off */
  os << "# Loop over all imported files and verify that they actually exist\n"
        "foreach(_cmake_target IN LISTS _cmake_import_check_targets)\n"
        "  if(CMAKE_VERSION VERSION_LESS \"3.28\"\n"
        "      OR NOT DEFINED "
        "_cmake_import_check_xcframework_for_${_cmake_target}\n"
        "      OR NOT IS_DIRECTORY "
        "\"${_cmake_import_check_xcframework_for_${_cmake_target}}\")\n"
        "    foreach(_cmake_file IN LISTS "
        "\"_cmake_import_check_files_for_${_cmake_target}\")\n"
        "      if(NOT EXISTS \"${_cmake_file}\")\n"
        "        message(FATAL_ERROR \"The imported target "
        "\\\"${_cmake_target}\\\" references the file\n"
        "   \\\"${_cmake_file}\\\"\n"
        "but this file does not exist.  Possible reasons include:\n"
        "* The file was deleted, renamed, or moved to another location.\n"
        "* An install or uninstall procedure did not complete successfully.\n"
        "* The installation package was faulty and contained\n"
        "   \\\"${CMAKE_CURRENT_LIST_FILE}\\\"\n"
        "but not all the files it references.\n"
        "\")\n"
        "      endif()\n"
        "    endforeach()\n"
        "  endif()\n"
        "  unset(_cmake_file)\n"
        "  unset(\"_cmake_import_check_files_for_${_cmake_target}\")\n"
        "endforeach()\n"
        "unset(_cmake_target)\n"
        "unset(_cmake_import_check_targets)\n"
        "\n";
  /* clang-format on */
}

void cmExportCMakeConfigGenerator::GenerateImportedFileChecksCode(
  std::ostream& os, cmGeneratorTarget const* target,
  ImportPropertyMap const& properties,
  std::set<std::string> const& importedLocations,
  std::string const& importedXcFrameworkLocation)
{
  // Construct the imported target name.
  std::string targetName = cmStrCat(this->Namespace, target->GetExportName());

  os << "list(APPEND _cmake_import_check_targets " << targetName << " )\n";
  if (!importedXcFrameworkLocation.empty()) {
    os << "set(_cmake_import_check_xcframework_for_" << targetName << ' '
       << cmExportFileGeneratorEscape(importedXcFrameworkLocation) << ")\n";
  }
  os << "list(APPEND _cmake_import_check_files_for_" << targetName << " ";

  for (std::string const& li : importedLocations) {
    auto pi = properties.find(li);
    if (pi != properties.end()) {
      os << cmExportFileGeneratorEscape(pi->second) << " ";
    }
  }

  os << ")\n\n";
}

void cmExportCMakeConfigGenerator::GenerateTargetFileSets(
  cmGeneratorTarget* gte, std::ostream& os, cmTargetExport const* te)
{
  auto interfaceFileSets = gte->Target->GetAllInterfaceFileSets();
  if (!interfaceFileSets.empty()) {
    std::string targetName = cmStrCat(this->Namespace, gte->GetExportName());
    os << "if(NOT CMAKE_VERSION VERSION_LESS \"3.23.0\")\n"
          "  target_sources("
       << targetName << "\n";

    for (auto const& name : interfaceFileSets) {
      auto* fileSet = gte->Target->GetFileSet(name);
      if (!fileSet) {
        gte->Makefile->IssueMessage(
          MessageType::FATAL_ERROR,
          cmStrCat("File set \"", name,
                   "\" is listed in interface file sets of ", gte->GetName(),
                   " but has not been created"));
        return;
      }

      os << "    INTERFACE"
         << "\n      FILE_SET " << cmOutputConverter::EscapeForCMake(name)
         << "\n      TYPE "
         << cmOutputConverter::EscapeForCMake(fileSet->GetType())
         << "\n      BASE_DIRS "
         << this->GetFileSetDirectories(gte, fileSet, te) << "\n      FILES "
         << this->GetFileSetFiles(gte, fileSet, te) << "\n";
    }

    os << "  )\nelse()\n  set_property(TARGET " << targetName
       << "\n    APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES";
    for (auto const& name : interfaceFileSets) {
      auto* fileSet = gte->Target->GetFileSet(name);
      if (!fileSet) {
        gte->Makefile->IssueMessage(
          MessageType::FATAL_ERROR,
          cmStrCat("File set \"", name,
                   "\" is listed in interface file sets of ", gte->GetName(),
                   " but has not been created"));
        return;
      }

      if (fileSet->GetType() == "HEADERS"_s) {
        os << "\n      " << this->GetFileSetDirectories(gte, fileSet, te);
      }
    }
    os << "\n  )\nendif()\n\n";
  }
}

std::string cmExportCMakeConfigGenerator::GetCxxModuleFile(
  std::string const& name) const
{
  auto const& cxxModuleDirname = this->GetCxxModulesDirectory();
  if (cxxModuleDirname.empty()) {
    return {};
  }

  return cmStrCat(cmSystemTools::GetFilenamePath(this->MainImportFile), '/',
                  cxxModuleDirname, "/cxx-modules-", name, ".cmake");
}

void cmExportCMakeConfigGenerator::GenerateCxxModuleInformation(
  std::string const& name, std::ostream& os)
{
  auto const cxx_module_dirname = this->GetCxxModulesDirectory();
  if (cxx_module_dirname.empty()) {
    return;
  }

  // Write the include.
  os << "# Include C++ module properties\n"
     << "include(\"${CMAKE_CURRENT_LIST_DIR}/" << cxx_module_dirname
     << "/cxx-modules-" << name << ".cmake\")\n\n";

  // Include all configuration-specific include files.
  cmGeneratedFileStream ap(this->GetCxxModuleFile(name), true);
  ap.SetCopyIfDifferent(true);

  this->GenerateCxxModuleConfigInformation(name, ap);
}

void cmExportCMakeConfigGenerator::SetRequiredCMakeVersion(unsigned int major,
                                                           unsigned int minor,
                                                           unsigned int patch)
{
  if (CMake_VERSION_ENCODE(major, minor, patch) >
      CMake_VERSION_ENCODE(this->RequiredCMakeVersionMajor,
                           this->RequiredCMakeVersionMinor,
                           this->RequiredCMakeVersionPatch)) {
    this->RequiredCMakeVersionMajor = major;
    this->RequiredCMakeVersionMinor = minor;
    this->RequiredCMakeVersionPatch = patch;
  }
}
