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

#include <algorithm>

#include <cm/memory>
#include <cm/string_view>

#include "cmsys/Directory.hxx"
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/SystemTools.hxx"

#include "cmAlgorithms.h"
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
#include "cmInstalledFile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmUuid.h"
#include "cmWIXDirectoriesSourceWriter.h"
#include "cmWIXFeaturesSourceWriter.h"
#include "cmWIXFilesSourceWriter.h"
#include "cmWIXRichTextFormatWriter.h"
#include "cmWIXSourceWriter.h"

#ifdef _WIN32
#  include <rpc.h> // for GUID generation (windows only)
#else
#  include <uuid/uuid.h> // for GUID generation (libuuid)
#endif

#include "cmCMakeToWixPath.h"

cmCPackWIXGenerator::cmCPackWIXGenerator()
  : ComponentGuidType(cmWIXSourceWriter::WIX_GENERATED_GUID)
{
}

cmCPackWIXGenerator::~cmCPackWIXGenerator() = default;

int cmCPackWIXGenerator::InitializeInternal()
{
  componentPackageMethod = ONE_PACKAGE;
  this->Patch = cm::make_unique<cmWIXPatch>(this->Logger);

  return this->Superclass::InitializeInternal();
}

bool cmCPackWIXGenerator::RunWiXCommand(std::string const& command)
{
  std::string logFileName = this->CPackTopLevel + "/wix.log";

  cmCPackLogger(cmCPackLog::LOG_DEBUG,
                "Running WiX command: " << command << std::endl);

  std::string output;

  int returnValue = 0;
  bool status = cmSystemTools::RunSingleCommand(
    command, &output, &output, &returnValue, 0, cmSystemTools::OUTPUT_NONE);

  cmsys::ofstream logFile(logFileName.c_str(), std::ios::app);
  logFile << command << std::endl;
  logFile << output;
  logFile.close();

  if (!status || returnValue) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Problem running WiX candle. "
                  "Please check '"
                    << logFileName << "' for errors." << std::endl);

    return false;
  }

  return true;
}

bool cmCPackWIXGenerator::RunCandleCommand(std::string const& sourceFile,
                                           std::string const& objectFile)
{
  std::string executable;
  if (!RequireOption("CPACK_WIX_CANDLE_EXECUTABLE", executable)) {
    return false;
  }

  std::ostringstream command;
  command << QuotePath(executable);
  command << " -nologo";
  command << " -arch " << GetArchitecture();
  command << " -out " << QuotePath(objectFile);

  for (std::string const& ext : CandleExtensions) {
    command << " -ext " << QuotePath(ext);
  }

  if (!cmHasSuffix(sourceFile, this->CPackTopLevel)) {
    command << " " << QuotePath("-I" + this->CPackTopLevel);
  }

  AddCustomFlags("CPACK_WIX_CANDLE_EXTRA_FLAGS", command);

  command << " " << QuotePath(sourceFile);

  return RunWiXCommand(command.str());
}

bool cmCPackWIXGenerator::RunLightCommand(std::string const& objectFiles)
{
  std::string executable;
  if (!RequireOption("CPACK_WIX_LIGHT_EXECUTABLE", executable)) {
    return false;
  }

  std::ostringstream command;
  command << QuotePath(executable);
  command << " -nologo";
  command << " -out " << QuotePath(CMakeToWixPath(packageFileNames.at(0)));

  for (std::string const& ext : this->LightExtensions) {
    command << " -ext " << QuotePath(ext);
  }

  const char* const cultures = GetOption("CPACK_WIX_CULTURES");
  if (cultures) {
    command << " -cultures:" << cultures;
  }

  AddCustomFlags("CPACK_WIX_LIGHT_EXTRA_FLAGS", command);

  command << " " << objectFiles;

  return RunWiXCommand(command.str());
}

int cmCPackWIXGenerator::PackageFiles()
{
  if (!PackageFilesImpl() || cmSystemTools::GetErrorOccuredFlag()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Fatal WiX Generator Error" << std::endl);
    return false;
  }

  return true;
}

bool cmCPackWIXGenerator::InitializeWiXConfiguration()
{
  if (!ReadListFile("Internal/CPack/CPackWIX.cmake")) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error while executing CPackWIX.cmake" << std::endl);
    return false;
  }

  if (GetOption("CPACK_WIX_PRODUCT_GUID") == 0) {
    std::string guid = GenerateGUID();
    SetOption("CPACK_WIX_PRODUCT_GUID", guid.c_str());

    cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                  "CPACK_WIX_PRODUCT_GUID implicitly set to " << guid << " . "
                                                              << std::endl);
  }

  if (GetOption("CPACK_WIX_UPGRADE_GUID") == 0) {
    std::string guid = GenerateGUID();
    SetOption("CPACK_WIX_UPGRADE_GUID", guid.c_str());

    cmCPackLogger(cmCPackLog::LOG_WARNING,
                  "CPACK_WIX_UPGRADE_GUID implicitly set to "
                    << guid
                    << " . "
                       "Please refer to the documentation on how and why "
                       "you might want to set this explicitly."
                    << std::endl);
  }

  if (!RequireOption("CPACK_TOPLEVEL_DIRECTORY", this->CPackTopLevel)) {
    return false;
  }

  if (GetOption("CPACK_WIX_LICENSE_RTF") == 0) {
    std::string licenseFilename = this->CPackTopLevel + "/License.rtf";
    SetOption("CPACK_WIX_LICENSE_RTF", licenseFilename.c_str());

    if (!CreateLicenseFile()) {
      return false;
    }
  }

  if (GetOption("CPACK_PACKAGE_VENDOR") == 0) {
    std::string defaultVendor = "Humanity";
    SetOption("CPACK_PACKAGE_VENDOR", defaultVendor.c_str());

    cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                  "CPACK_PACKAGE_VENDOR implicitly set to "
                    << defaultVendor << " . " << std::endl);
  }

  if (GetOption("CPACK_WIX_UI_REF") == 0) {
    std::string defaultRef = "WixUI_InstallDir";

    if (!this->Components.empty()) {
      defaultRef = "WixUI_FeatureTree";
    }

    SetOption("CPACK_WIX_UI_REF", defaultRef.c_str());
  }

  const char* packageContact = GetOption("CPACK_PACKAGE_CONTACT");
  if (packageContact != 0 && GetOption("CPACK_WIX_PROPERTY_ARPCONTACT") == 0) {
    SetOption("CPACK_WIX_PROPERTY_ARPCONTACT", packageContact);
  }

  CollectExtensions("CPACK_WIX_EXTENSIONS", this->CandleExtensions);
  CollectExtensions("CPACK_WIX_CANDLE_EXTENSIONS", this->CandleExtensions);

  this->LightExtensions.insert("WixUIExtension");
  CollectExtensions("CPACK_WIX_EXTENSIONS", this->LightExtensions);
  CollectExtensions("CPACK_WIX_LIGHT_EXTENSIONS", this->LightExtensions);

  const char* patchFilePath = GetOption("CPACK_WIX_PATCH_FILE");
  if (patchFilePath) {
    std::vector<std::string> patchFilePaths = cmExpandedList(patchFilePath);

    for (std::string const& p : patchFilePaths) {
      if (!this->Patch->LoadFragments(p)) {
        return false;
      }
    }
  }

  // if install folder is supposed to be set absolutely, the default
  // component guid "*" cannot be used
  if (cmIsOn(GetOption("CPACK_WIX_SKIP_PROGRAM_FOLDER"))) {
    this->ComponentGuidType = cmWIXSourceWriter::CMAKE_GENERATED_GUID;
  }

  return true;
}

bool cmCPackWIXGenerator::PackageFilesImpl()
{
  if (!InitializeWiXConfiguration()) {
    return false;
  }

  CreateWiXVariablesIncludeFile();
  CreateWiXPropertiesIncludeFile();
  CreateWiXProductFragmentIncludeFile();

  if (!CreateWiXSourceFiles()) {
    return false;
  }

  AppendUserSuppliedExtraSources();

  std::set<std::string> usedBaseNames;

  std::ostringstream objectFiles;
  for (std::string const& sourceFilename : this->WixSources) {
    std::string baseName =
      cmSystemTools::GetFilenameWithoutLastExtension(sourceFilename);

    unsigned int counter = 0;
    std::string uniqueBaseName = baseName;

    while (usedBaseNames.find(uniqueBaseName) != usedBaseNames.end()) {
      std::ostringstream tmp;
      tmp << baseName << ++counter;
      uniqueBaseName = tmp.str();
    }

    usedBaseNames.insert(uniqueBaseName);

    std::string objectFilename =
      this->CPackTopLevel + "/" + uniqueBaseName + ".wixobj";

    if (!RunCandleCommand(CMakeToWixPath(sourceFilename),
                          CMakeToWixPath(objectFilename))) {
      return false;
    }

    objectFiles << " " << QuotePath(CMakeToWixPath(objectFilename));
  }

  AppendUserSuppliedExtraObjects(objectFiles);

  return RunLightCommand(objectFiles.str());
}

void cmCPackWIXGenerator::AppendUserSuppliedExtraSources()
{
  const char* cpackWixExtraSources = GetOption("CPACK_WIX_EXTRA_SOURCES");
  if (!cpackWixExtraSources)
    return;

  cmExpandList(cpackWixExtraSources, this->WixSources);
}

void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream)
{
  const char* cpackWixExtraObjects = GetOption("CPACK_WIX_EXTRA_OBJECTS");
  if (!cpackWixExtraObjects)
    return;

  std::vector<std::string> expandedExtraObjects =
    cmExpandedList(cpackWixExtraObjects);

  for (std::string const& obj : expandedExtraObjects) {
    stream << " " << QuotePath(obj);
  }
}

void cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
{
  std::string includeFilename = this->CPackTopLevel + "/cpack_variables.wxi";

  cmWIXSourceWriter includeFile(this->Logger, includeFilename,
                                this->ComponentGuidType,
                                cmWIXSourceWriter::INCLUDE_ELEMENT_ROOT);

  CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_GUID");
  CopyDefinition(includeFile, "CPACK_WIX_UPGRADE_GUID");
  CopyDefinition(includeFile, "CPACK_PACKAGE_VENDOR");
  CopyDefinition(includeFile, "CPACK_PACKAGE_NAME");
  CopyDefinition(includeFile, "CPACK_PACKAGE_VERSION");
  CopyDefinition(includeFile, "CPACK_WIX_LICENSE_RTF", DefinitionType::PATH);
  CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_ICON", DefinitionType::PATH);
  CopyDefinition(includeFile, "CPACK_WIX_UI_BANNER", DefinitionType::PATH);
  CopyDefinition(includeFile, "CPACK_WIX_UI_DIALOG", DefinitionType::PATH);
  SetOptionIfNotSet("CPACK_WIX_PROGRAM_MENU_FOLDER",
                    GetOption("CPACK_PACKAGE_NAME"));
  CopyDefinition(includeFile, "CPACK_WIX_PROGRAM_MENU_FOLDER");
  CopyDefinition(includeFile, "CPACK_WIX_UI_REF");
}

void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile()
{
  std::string includeFilename = this->CPackTopLevel + "/properties.wxi";

  cmWIXSourceWriter includeFile(this->Logger, includeFilename,
                                this->ComponentGuidType,
                                cmWIXSourceWriter::INCLUDE_ELEMENT_ROOT);

  std::string prefix = "CPACK_WIX_PROPERTY_";
  std::vector<std::string> options = GetOptions();

  for (std::string const& name : options) {
    if (cmHasPrefix(name, prefix)) {
      std::string id = name.substr(prefix.length());
      std::string value = GetOption(name.c_str());

      includeFile.BeginElement("Property");
      includeFile.AddAttribute("Id", id);
      includeFile.AddAttribute("Value", value);
      includeFile.EndElement("Property");
    }
  }

  if (GetOption("CPACK_WIX_PROPERTY_ARPINSTALLLOCATION") == 0) {
    includeFile.BeginElement("Property");
    includeFile.AddAttribute("Id", "INSTALL_ROOT");
    includeFile.AddAttribute("Secure", "yes");

    includeFile.BeginElement("RegistrySearch");
    includeFile.AddAttribute("Id", "FindInstallLocation");
    includeFile.AddAttribute("Root", "HKLM");
    includeFile.AddAttribute(
      "Key",
      "Software\\Microsoft\\Windows\\"
      "CurrentVersion\\Uninstall\\[WIX_UPGRADE_DETECTED]");
    includeFile.AddAttribute("Name", "InstallLocation");
    includeFile.AddAttribute("Type", "raw");
    includeFile.EndElement("RegistrySearch");
    includeFile.EndElement("Property");

    includeFile.BeginElement("SetProperty");
    includeFile.AddAttribute("Id", "ARPINSTALLLOCATION");
    includeFile.AddAttribute("Value", "[INSTALL_ROOT]");
    includeFile.AddAttribute("After", "CostFinalize");
    includeFile.EndElement("SetProperty");
  }
}

void cmCPackWIXGenerator::CreateWiXProductFragmentIncludeFile()
{
  std::string includeFilename = this->CPackTopLevel + "/product_fragment.wxi";

  cmWIXSourceWriter includeFile(this->Logger, includeFilename,
                                this->ComponentGuidType,
                                cmWIXSourceWriter::INCLUDE_ELEMENT_ROOT);

  this->Patch->ApplyFragment("#PRODUCT", includeFile);
}

void cmCPackWIXGenerator::CopyDefinition(cmWIXSourceWriter& source,
                                         std::string const& name,
                                         DefinitionType type)
{
  const char* value = GetOption(name.c_str());
  if (value) {
    if (type == DefinitionType::PATH) {
      AddDefinition(source, name, CMakeToWixPath(value));
    } else {
      AddDefinition(source, name, value);
    }
  }
}

void cmCPackWIXGenerator::AddDefinition(cmWIXSourceWriter& source,
                                        std::string const& name,
                                        std::string const& value)
{
  std::ostringstream tmp;
  tmp << name << "=\"" << value << '"';

  source.AddProcessingInstruction("define", tmp.str());
}

bool cmCPackWIXGenerator::CreateWiXSourceFiles()
{
  // if install folder is supposed to be set absolutely, the default
  // component guid "*" cannot be used
  std::string directoryDefinitionsFilename =
    this->CPackTopLevel + "/directories.wxs";

  this->WixSources.push_back(directoryDefinitionsFilename);

  cmWIXDirectoriesSourceWriter directoryDefinitions(
    this->Logger, directoryDefinitionsFilename, this->ComponentGuidType);
  directoryDefinitions.BeginElement("Fragment");

  std::string installRoot;
  if (!RequireOption("CPACK_PACKAGE_INSTALL_DIRECTORY", installRoot)) {
    return false;
  }

  directoryDefinitions.BeginElement("Directory");
  directoryDefinitions.AddAttribute("Id", "TARGETDIR");
  directoryDefinitions.AddAttribute("Name", "SourceDir");

  size_t installRootSize =
    directoryDefinitions.BeginInstallationPrefixDirectory(GetRootFolderId(),
                                                          installRoot);

  std::string fileDefinitionsFilename = this->CPackTopLevel + "/files.wxs";

  this->WixSources.push_back(fileDefinitionsFilename);

  cmWIXFilesSourceWriter fileDefinitions(this->Logger, fileDefinitionsFilename,
                                         this->ComponentGuidType);

  fileDefinitions.BeginElement("Fragment");

  std::string featureDefinitionsFilename =
    this->CPackTopLevel + "/features.wxs";

  this->WixSources.push_back(featureDefinitionsFilename);

  cmWIXFeaturesSourceWriter featureDefinitions(
    this->Logger, featureDefinitionsFilename, this->ComponentGuidType);

  featureDefinitions.BeginElement("Fragment");

  featureDefinitions.BeginElement("Feature");
  featureDefinitions.AddAttribute("Id", "ProductFeature");
  featureDefinitions.AddAttribute("Display", "expand");
  featureDefinitions.AddAttribute("Absent", "disallow");
  featureDefinitions.AddAttribute("ConfigurableDirectory", "INSTALL_ROOT");

  std::string cpackPackageName;
  if (!RequireOption("CPACK_PACKAGE_NAME", cpackPackageName)) {
    return false;
  }

  std::string featureTitle = cpackPackageName;
  if (const char* title = GetOption("CPACK_WIX_ROOT_FEATURE_TITLE")) {
    featureTitle = title;
  }
  featureDefinitions.AddAttribute("Title", featureTitle);
  if (const char* desc = GetOption("CPACK_WIX_ROOT_FEATURE_DESCRIPTION")) {
    featureDefinitions.AddAttribute("Description", desc);
  }
  featureDefinitions.AddAttribute("Level", "1");
  this->Patch->ApplyFragment("#PRODUCTFEATURE", featureDefinitions);

  const char* package = GetOption("CPACK_WIX_CMAKE_PACKAGE_REGISTRY");
  if (package) {
    featureDefinitions.CreateCMakePackageRegistryEntry(
      package, GetOption("CPACK_WIX_UPGRADE_GUID"));
  }

  if (!CreateFeatureHierarchy(featureDefinitions)) {
    return false;
  }

  featureDefinitions.EndElement("Feature");

  std::set<cmWIXShortcuts::Type> emittedShortcutTypes;

  cmWIXShortcuts globalShortcuts;
  if (Components.empty()) {
    AddComponentsToFeature(toplevel, "ProductFeature", directoryDefinitions,
                           fileDefinitions, featureDefinitions,
                           globalShortcuts);

    globalShortcuts.AddShortcutTypes(emittedShortcutTypes);
  } else {
    for (auto const& i : this->Components) {
      cmCPackComponent const& component = i.second;

      std::string componentPath = cmStrCat(toplevel, '/', component.Name);

      std::string const componentFeatureId = "CM_C_" + component.Name;

      cmWIXShortcuts featureShortcuts;
      AddComponentsToFeature(componentPath, componentFeatureId,
                             directoryDefinitions, fileDefinitions,
                             featureDefinitions, featureShortcuts);

      featureShortcuts.AddShortcutTypes(emittedShortcutTypes);

      if (!CreateShortcuts(component.Name, componentFeatureId,
                           featureShortcuts, false, fileDefinitions,
                           featureDefinitions)) {
        return false;
      }
    }
  }

  bool emitUninstallShortcut = true;
  const char* cpackWixProgramMenuFolder =
    GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER");
  if (cpackWixProgramMenuFolder &&
      cm::string_view(cpackWixProgramMenuFolder) == ".") {
    emitUninstallShortcut = false;
  } else if (emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) ==
             emittedShortcutTypes.end()) {
    emitUninstallShortcut = false;
  }

  if (!CreateShortcuts(std::string(), "ProductFeature", globalShortcuts,
                       emitUninstallShortcut, fileDefinitions,
                       featureDefinitions)) {
    return false;
  }

  featureDefinitions.EndElement("Fragment");
  fileDefinitions.EndElement("Fragment");

  directoryDefinitions.EndInstallationPrefixDirectory(installRootSize);

  if (emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) !=
      emittedShortcutTypes.end()) {
    directoryDefinitions.EmitStartMenuFolder(
      GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"));
  }

  if (emittedShortcutTypes.find(cmWIXShortcuts::DESKTOP) !=
      emittedShortcutTypes.end()) {
    directoryDefinitions.EmitDesktopFolder();
  }

  if (emittedShortcutTypes.find(cmWIXShortcuts::STARTUP) !=
      emittedShortcutTypes.end()) {
    directoryDefinitions.EmitStartupFolder();
  }

  directoryDefinitions.EndElement("Directory");
  directoryDefinitions.EndElement("Fragment");

  if (!GenerateMainSourceFileFromTemplate()) {
    return false;
  }

  return this->Patch->CheckForUnappliedFragments();
}

std::string cmCPackWIXGenerator::GetRootFolderId() const
{
  if (cmIsOn(GetOption("CPACK_WIX_SKIP_PROGRAM_FOLDER"))) {
    return "";
  }

  std::string result = "ProgramFiles<64>Folder";

  const char* rootFolderId = GetOption("CPACK_WIX_ROOT_FOLDER_ID");
  if (rootFolderId) {
    result = rootFolderId;
  }

  if (GetArchitecture() == "x86") {
    cmSystemTools::ReplaceString(result, "<64>", "");
  } else {
    cmSystemTools::ReplaceString(result, "<64>", "64");
  }

  return result;
}

bool cmCPackWIXGenerator::GenerateMainSourceFileFromTemplate()
{
  std::string wixTemplate = FindTemplate("WIX.template.in");
  if (GetOption("CPACK_WIX_TEMPLATE") != 0) {
    wixTemplate = GetOption("CPACK_WIX_TEMPLATE");
  }

  if (wixTemplate.empty()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Could not find CPack WiX template file WIX.template.in"
                    << std::endl);
    return false;
  }

  std::string mainSourceFilePath = this->CPackTopLevel + "/main.wxs";

  if (!ConfigureFile(wixTemplate, mainSourceFilePath)) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Failed creating '" << mainSourceFilePath
                                      << "'' from template." << std::endl);

    return false;
  }

  this->WixSources.push_back(mainSourceFilePath);

  return true;
}

bool cmCPackWIXGenerator::CreateFeatureHierarchy(
  cmWIXFeaturesSourceWriter& featureDefinitions)
{
  for (auto const& i : ComponentGroups) {
    cmCPackComponentGroup const& group = i.second;
    if (group.ParentGroup == 0) {
      featureDefinitions.EmitFeatureForComponentGroup(group, *this->Patch);
    }
  }

  for (auto const& i : this->Components) {
    cmCPackComponent const& component = i.second;

    if (!component.Group) {
      featureDefinitions.EmitFeatureForComponent(component, *this->Patch);
    }
  }

  return true;
}

bool cmCPackWIXGenerator::AddComponentsToFeature(
  std::string const& rootPath, std::string const& featureId,
  cmWIXDirectoriesSourceWriter& directoryDefinitions,
  cmWIXFilesSourceWriter& fileDefinitions,
  cmWIXFeaturesSourceWriter& featureDefinitions, cmWIXShortcuts& shortcuts)
{
  featureDefinitions.BeginElement("FeatureRef");
  featureDefinitions.AddAttribute("Id", featureId);

  std::vector<std::string> cpackPackageExecutablesList;
  const char* cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES");
  if (cpackPackageExecutables) {
    cmExpandList(cpackPackageExecutables, cpackPackageExecutablesList);
    if (cpackPackageExecutablesList.size() % 2 != 0) {
      cmCPackLogger(
        cmCPackLog::LOG_ERROR,
        "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
        "<text label>."
          << std::endl);
      return false;
    }
  }

  std::vector<std::string> cpackPackageDesktopLinksList;
  const char* cpackPackageDesktopLinks =
    GetOption("CPACK_CREATE_DESKTOP_LINKS");
  if (cpackPackageDesktopLinks) {
    cmExpandList(cpackPackageDesktopLinks, cpackPackageDesktopLinksList);
  }

  AddDirectoryAndFileDefinitions(
    rootPath, "INSTALL_ROOT", directoryDefinitions, fileDefinitions,
    featureDefinitions, cpackPackageExecutablesList,
    cpackPackageDesktopLinksList, shortcuts);

  featureDefinitions.EndElement("FeatureRef");

  return true;
}

bool cmCPackWIXGenerator::CreateShortcuts(
  std::string const& cpackComponentName, std::string const& featureId,
  cmWIXShortcuts const& shortcuts, bool emitUninstallShortcut,
  cmWIXFilesSourceWriter& fileDefinitions,
  cmWIXFeaturesSourceWriter& featureDefinitions)
{
  if (!shortcuts.empty(cmWIXShortcuts::START_MENU)) {
    if (!this->CreateShortcutsOfSpecificType(
          cmWIXShortcuts::START_MENU, cpackComponentName, featureId, "",
          shortcuts, emitUninstallShortcut, fileDefinitions,
          featureDefinitions)) {
      return false;
    }
  }

  if (!shortcuts.empty(cmWIXShortcuts::DESKTOP)) {
    if (!this->CreateShortcutsOfSpecificType(
          cmWIXShortcuts::DESKTOP, cpackComponentName, featureId, "DESKTOP",
          shortcuts, false, fileDefinitions, featureDefinitions)) {
      return false;
    }
  }

  if (!shortcuts.empty(cmWIXShortcuts::STARTUP)) {
    if (!this->CreateShortcutsOfSpecificType(
          cmWIXShortcuts::STARTUP, cpackComponentName, featureId, "STARTUP",
          shortcuts, false, fileDefinitions, featureDefinitions)) {
      return false;
    }
  }

  return true;
}

bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
  cmWIXShortcuts::Type type, std::string const& cpackComponentName,
  std::string const& featureId, std::string const& idPrefix,
  cmWIXShortcuts const& shortcuts, bool emitUninstallShortcut,
  cmWIXFilesSourceWriter& fileDefinitions,
  cmWIXFeaturesSourceWriter& featureDefinitions)
{
  std::string directoryId;
  switch (type) {
    case cmWIXShortcuts::START_MENU: {
      const char* cpackWixProgramMenuFolder =
        GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER");
      if (cpackWixProgramMenuFolder &&
          cm::string_view(cpackWixProgramMenuFolder) == ".") {
        directoryId = "ProgramMenuFolder";
      } else {
        directoryId = "PROGRAM_MENU_FOLDER";
      }
    } break;
    case cmWIXShortcuts::DESKTOP:
      directoryId = "DesktopFolder";
      break;
    case cmWIXShortcuts::STARTUP:
      directoryId = "StartupFolder";
      break;
    default:
      return false;
  }

  featureDefinitions.BeginElement("FeatureRef");
  featureDefinitions.AddAttribute("Id", featureId);

  std::string cpackVendor;
  if (!RequireOption("CPACK_PACKAGE_VENDOR", cpackVendor)) {
    return false;
  }

  std::string cpackPackageName;
  if (!RequireOption("CPACK_PACKAGE_NAME", cpackPackageName)) {
    return false;
  }

  std::string idSuffix;
  if (!cpackComponentName.empty()) {
    idSuffix += "_";
    idSuffix += cpackComponentName;
  }

  std::string componentId = "CM_SHORTCUT";
  if (idPrefix.size()) {
    componentId += "_" + idPrefix;
  }

  componentId += idSuffix;

  fileDefinitions.BeginElement("DirectoryRef");
  fileDefinitions.AddAttribute("Id", directoryId);

  fileDefinitions.BeginElement("Component");
  fileDefinitions.AddAttribute("Id", componentId);
  fileDefinitions.AddAttribute(
    "Guid", fileDefinitions.CreateGuidFromComponentId(componentId));

  this->Patch->ApplyFragment(componentId, fileDefinitions);

  std::string registryKey =
    std::string("Software\\") + cpackVendor + "\\" + cpackPackageName;

  shortcuts.EmitShortcuts(type, registryKey, cpackComponentName,
                          fileDefinitions);

  if (type == cmWIXShortcuts::START_MENU) {
    const char* cpackWixProgramMenuFolder =
      GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER");
    if (cpackWixProgramMenuFolder &&
        cm::string_view(cpackWixProgramMenuFolder) != ".") {
      fileDefinitions.EmitRemoveFolder("CM_REMOVE_PROGRAM_MENU_FOLDER" +
                                       idSuffix);
    }
  }

  if (emitUninstallShortcut) {
    fileDefinitions.EmitUninstallShortcut(cpackPackageName);
  }

  fileDefinitions.EndElement("Component");
  fileDefinitions.EndElement("DirectoryRef");

  featureDefinitions.EmitComponentRef(componentId);
  featureDefinitions.EndElement("FeatureRef");

  return true;
}

bool cmCPackWIXGenerator::CreateLicenseFile()
{
  std::string licenseSourceFilename;
  if (!RequireOption("CPACK_RESOURCE_FILE_LICENSE", licenseSourceFilename)) {
    return false;
  }

  std::string licenseDestinationFilename;
  if (!RequireOption("CPACK_WIX_LICENSE_RTF", licenseDestinationFilename)) {
    return false;
  }

  std::string extension = GetRightmostExtension(licenseSourceFilename);

  if (extension == ".rtf") {
    cmSystemTools::CopyAFile(licenseSourceFilename.c_str(),
                             licenseDestinationFilename.c_str());
  } else if (extension == ".txt") {
    cmWIXRichTextFormatWriter rtfWriter(licenseDestinationFilename);

    cmsys::ifstream licenseSource(licenseSourceFilename.c_str());

    std::string line;
    while (std::getline(licenseSource, line)) {
      rtfWriter.AddText(line);
      rtfWriter.AddText("\n");
    }
  } else {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "unsupported WiX License file extension '"
                    << extension << "'" << std::endl);

    return false;
  }

  return true;
}

void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions(
  std::string const& topdir, std::string const& directoryId,
  cmWIXDirectoriesSourceWriter& directoryDefinitions,
  cmWIXFilesSourceWriter& fileDefinitions,
  cmWIXFeaturesSourceWriter& featureDefinitions,
  std::vector<std::string> const& packageExecutables,
  std::vector<std::string> const& desktopExecutables,
  cmWIXShortcuts& shortcuts)
{
  cmsys::Directory dir;
  dir.Load(topdir.c_str());

  std::string relativeDirectoryPath =
    cmSystemTools::RelativePath(toplevel.c_str(), topdir.c_str());

  if (relativeDirectoryPath.empty()) {
    relativeDirectoryPath = ".";
  }

  cmInstalledFile const* directoryInstalledFile = this->GetInstalledFile(
    this->RelativePathWithoutComponentPrefix(relativeDirectoryPath));

  bool emptyDirectory = dir.GetNumberOfFiles() == 2;
  bool createDirectory = false;

  if (emptyDirectory) {
    createDirectory = true;
  }

  if (directoryInstalledFile) {
    if (directoryInstalledFile->HasProperty("CPACK_WIX_ACL")) {
      createDirectory = true;
    }
  }

  if (createDirectory) {
    std::string componentId = fileDefinitions.EmitComponentCreateFolder(
      directoryId, GenerateGUID(), directoryInstalledFile);
    featureDefinitions.EmitComponentRef(componentId);
  }

  if (emptyDirectory) {
    return;
  }

  for (size_t i = 0; i < dir.GetNumberOfFiles(); ++i) {
    std::string fileName = dir.GetFile(static_cast<unsigned long>(i));

    if (fileName == "." || fileName == "..") {
      continue;
    }

    std::string fullPath = topdir + "/" + fileName;

    std::string relativePath =
      cmSystemTools::RelativePath(toplevel.c_str(), fullPath.c_str());

    std::string id = PathToId(relativePath);

    if (cmSystemTools::FileIsDirectory(fullPath.c_str())) {
      std::string subDirectoryId = std::string("CM_D") + id;

      directoryDefinitions.BeginElement("Directory");
      directoryDefinitions.AddAttribute("Id", subDirectoryId);
      directoryDefinitions.AddAttribute("Name", fileName);
      this->Patch->ApplyFragment(subDirectoryId, directoryDefinitions);

      AddDirectoryAndFileDefinitions(
        fullPath, subDirectoryId, directoryDefinitions, fileDefinitions,
        featureDefinitions, packageExecutables, desktopExecutables, shortcuts);

      directoryDefinitions.EndElement("Directory");
    } else {
      cmInstalledFile const* installedFile = this->GetInstalledFile(
        this->RelativePathWithoutComponentPrefix(relativePath));

      if (installedFile) {
        shortcuts.CreateFromProperties(id, directoryId, *installedFile);
      }

      std::string componentId = fileDefinitions.EmitComponentFile(
        directoryId, id, fullPath, *(this->Patch), installedFile);

      featureDefinitions.EmitComponentRef(componentId);

      for (size_t j = 0; j < packageExecutables.size(); ++j) {
        std::string const& executableName = packageExecutables[j++];
        std::string const& textLabel = packageExecutables[j];

        if (cmSystemTools::LowerCase(fileName) ==
            cmSystemTools::LowerCase(executableName) + ".exe") {
          cmWIXShortcut shortcut;
          shortcut.label = textLabel;
          shortcut.workingDirectoryId = directoryId;
          shortcuts.insert(cmWIXShortcuts::START_MENU, id, shortcut);

          if (cmContains(desktopExecutables, executableName)) {
            shortcuts.insert(cmWIXShortcuts::DESKTOP, id, shortcut);
          }
        }
      }
    }
  }
}

bool cmCPackWIXGenerator::RequireOption(std::string const& name,
                                        std::string& value) const
{
  const char* tmp = GetOption(name.c_str());
  if (tmp) {
    value = tmp;

    return true;
  } else {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Required variable " << name << " not set" << std::endl);

    return false;
  }
}

std::string cmCPackWIXGenerator::GetArchitecture() const
{
  std::string void_p_size;
  RequireOption("CPACK_WIX_SIZEOF_VOID_P", void_p_size);

  if (void_p_size == "8") {
    return "x64";
  } else {
    return "x86";
  }
}

std::string cmCPackWIXGenerator::GenerateGUID()
{
#ifdef _WIN32
  UUID guid;
  UuidCreate(&guid);

  unsigned short* tmp = 0;
  UuidToStringW(&guid, &tmp);

  std::string result =
    cmsys::Encoding::ToNarrow(reinterpret_cast<wchar_t*>(tmp));
  RpcStringFreeW(&tmp);
#else
  uuid_t guid;
  char guid_ch[37] = { 0 };

  uuid_generate(guid);
  uuid_unparse(guid, guid_ch);
  std::string result = guid_ch;
#endif

  return cmSystemTools::UpperCase(result);
}

std::string cmCPackWIXGenerator::QuotePath(std::string const& path)
{
  return std::string("\"") + path + '"';
}

std::string cmCPackWIXGenerator::GetRightmostExtension(
  std::string const& filename)
{
  std::string extension;

  std::string::size_type i = filename.rfind(".");
  if (i != std::string::npos) {
    extension = filename.substr(i);
  }

  return cmSystemTools::LowerCase(extension);
}

std::string cmCPackWIXGenerator::PathToId(std::string const& path)
{
  id_map_t::const_iterator i = PathToIdMap.find(path);
  if (i != PathToIdMap.end())
    return i->second;

  std::string id = CreateNewIdForPath(path);
  return id;
}

std::string cmCPackWIXGenerator::CreateNewIdForPath(std::string const& path)
{
  std::vector<std::string> components;
  cmSystemTools::SplitPath(path.c_str(), components, false);

  size_t replacementCount = 0;

  std::string identifier;
  std::string currentComponent;

  for (size_t i = 1; i < components.size(); ++i) {
    if (i != 1)
      identifier += '.';

    currentComponent =
      NormalizeComponentForId(components[i], replacementCount);

    identifier += currentComponent;
  }

  std::string idPrefix = "P";
  size_t replacementPercent = replacementCount * 100 / identifier.size();
  if (replacementPercent > 33 || identifier.size() > 60) {
    identifier = CreateHashedId(path, currentComponent);
    idPrefix = "H";
  }

  std::ostringstream result;
  result << idPrefix << "_" << identifier;

  size_t ambiguityCount = ++IdAmbiguityCounter[identifier];

  if (ambiguityCount > 999) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error while trying to generate a unique Id for '"
                    << path << "'" << std::endl);

    return std::string();
  } else if (ambiguityCount > 1) {
    result << "_" << ambiguityCount;
  }

  std::string resultString = result.str();

  PathToIdMap[path] = resultString;

  return resultString;
}

std::string cmCPackWIXGenerator::CreateHashedId(
  std::string const& path, std::string const& normalizedFilename)
{
  cmCryptoHash sha1(cmCryptoHash::AlgoSHA1);
  std::string const hash = sha1.HashString(path);

  const size_t maxFileNameLength = 52;
  std::string identifier =
    cmStrCat(cm::string_view(hash).substr(0, 7), '_',
             cm::string_view(normalizedFilename).substr(0, maxFileNameLength));

  // if the name was truncated
  if (normalizedFilename.length() > maxFileNameLength) {
    identifier += "...";
  }

  return identifier;
}

std::string cmCPackWIXGenerator::NormalizeComponentForId(
  std::string const& component, size_t& replacementCount)
{
  std::string result;
  result.resize(component.size());

  for (size_t i = 0; i < component.size(); ++i) {
    char c = component[i];
    if (IsLegalIdCharacter(c)) {
      result[i] = c;
    } else {
      result[i] = '_';
      ++replacementCount;
    }
  }

  return result;
}

bool cmCPackWIXGenerator::IsLegalIdCharacter(char c)
{
  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
    (c >= 'A' && c <= 'Z') || c == '_' || c == '.';
}

void cmCPackWIXGenerator::CollectExtensions(std::string const& variableName,
                                            extension_set_t& extensions)
{
  const char* variableContent = GetOption(variableName.c_str());
  if (!variableContent)
    return;

  std::vector<std::string> list = cmExpandedList(variableContent);
  extensions.insert(list.begin(), list.end());
}

void cmCPackWIXGenerator::AddCustomFlags(std::string const& variableName,
                                         std::ostream& stream)
{
  const char* variableContent = GetOption(variableName.c_str());
  if (!variableContent)
    return;

  std::vector<std::string> list = cmExpandedList(variableContent);

  for (std::string const& i : list) {
    stream << " " << QuotePath(i);
  }
}

std::string cmCPackWIXGenerator::RelativePathWithoutComponentPrefix(
  std::string const& path)
{
  if (this->Components.empty()) {
    return path;
  }

  std::string::size_type pos = path.find('/');

  return path.substr(pos + 1);
}
