/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst 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 "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmValue.h"
#include "cmVersionMacros.h"

struct cmLinkInterface;

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;
  }

  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;
  }

  if (!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"
        "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 4.0 (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 << "...4.0)\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.
  os << "# Commands may need to know the format version.\n"
        "set(CMAKE_IMPORT_FILE_VERSION 1)\n"
        "\n";
}

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:
      if (target->IsSymbolic()) {
        os << "if(CMAKE_VERSION VERSION_GREATER_EQUAL \"4.2.0\")\n"
              "  add_library("
           << targetName << " INTERFACE SYMBOLIC IMPORTED)\n"
           << "elseif(CMAKE_VERSION VERSION_GREATER_EQUAL 3.2.0)\n"
           << "  add_library(" << targetName << " INTERFACE IMPORTED)\n"
           << "  set_target_properties(" << targetName
           << " PROPERTIES SYMBOLIC TRUE)\n"
           << "endif()\n";
      } else {
        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";
  }

  // Mark the imported library if it is an AIX shared library archive.
  if (target->IsArchivedAIXSharedLibrary()) {
    os << "set_property(TARGET " << targetName
       << " PROPERTY AIX_SHARED_LIBRARY_ARCHIVE 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"
        "set_property(TARGET "
     << targetName << " APPEND PROPERTY IMPORTED_CONFIGURATIONS ";
  if (!config.empty()) {
    os << cmSystemTools::UpperCase(config);
  } else {
    os << "NOCONFIG";
  }
  os << ")\n"
        "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;
    });

  // Unwinding is only valid in a find_package() context
  os << "if(DEFINED CMAKE_FIND_PACKAGE_NAME)\n"
     << "  set(_cmake_unwind_arg UNWIND_INCLUDE)\n"
     << "endif()\n\n";

  for (auto const& it : packageDependenciesSorted) {
    if (it.second.Enabled == cmExportSet::PackageDependencyExportEnabled::On) {
      os << "__find_dependency_no_return(" << it.first;
      for (auto const& arg : it.second.ExtraArguments) {
        os << ' ' << cmOutputConverter::EscapeForCMake(arg);
      }
      os << " ${_cmake_unwind_arg})\n";
      os << "if(NOT " << it.first << "_FOUND)\n"
         << "  unset(_cmake_unwind_arg)\n"
         << "  cmake_policy(POP)\n"
         << "  return()\n"
         << "endif()\n\n";
    }
  }

  os << "unset(_cmake_unwind_arg)\n\n\n";
}

void cmExportCMakeConfigGenerator::GenerateMissingTargetsCheckCode(
  std::ostream& os)
{
  if (this->MissingTargets.empty()) {
    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";
    return;
  }
  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 ";
  std::set<std::string> emitted;
  for (std::string const& missingTarget : this->MissingTargets) {
    if (emitted.insert(missingTarget).second) {
      os << '"' << missingTarget << "\" ";
    }
  }
  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";
}

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.).
  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";
}

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;
  }
}
