/* 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 "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
#include "cmInstalledFile.h"
#include "cmSystemTools.h"
#include "cmUuid.h"
#include <algorithm>

#include "cmWIXDirectoriesSourceWriter.h"
#include "cmWIXFeaturesSourceWriter.h"
#include "cmWIXFilesSourceWriter.h"
#include "cmWIXRichTextFormatWriter.h"
#include "cmWIXSourceWriter.h"

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

#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()
  : Patch(0)
  , ComponentGuidType(cmWIXSourceWriter::WIX_GENERATED_GUID)
{
}

cmCPackWIXGenerator::~cmCPackWIXGenerator()
{
  if (this->Patch) {
    delete this->Patch;
  }
}

int cmCPackWIXGenerator::InitializeInternal()
{
  componentPackageMethod = ONE_PACKAGE;
  this->Patch = new 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 (sourceFile.rfind(this->CPackTopLevel, 0) != 0) {
    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;
    cmSystemTools::ExpandListArgument(patchFilePath, patchFilePaths);

    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 (cmSystemTools::IsOn(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;

  cmSystemTools::ExpandListArgument(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;

  cmSystemTools::ExpandListArgument(cpackWixExtraObjects,
                                    expandedExtraObjects);

  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 (name.length() > prefix.length() &&
        name.substr(0, prefix.length()) == 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 = toplevel;
      componentPath += "/";
      componentPath += 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 =
    emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) !=
    emittedShortcutTypes.end();

  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 (cmSystemTools::IsOn(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) {
    cmSystemTools::ExpandListArgument(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) {
    cmSystemTools::ExpandListArgument(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:
      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) {
    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 (!desktopExecutables.empty() &&
              std::find(desktopExecutables.begin(), desktopExecutables.end(),
                        executableName) != desktopExecutables.end()) {
            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);

  std::string identifier;
  identifier += hash.substr(0, 7) + "_";

  const size_t maxFileNameLength = 52;
  if (normalizedFilename.length() > maxFileNameLength) {
    identifier += normalizedFilename.substr(0, maxFileNameLength - 3);
    identifier += "...";
  } else {
    identifier += normalizedFilename;
  }

  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;
  cmSystemTools::ExpandListArgument(variableContent, list);
  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;
  cmSystemTools::ExpandListArgument(variableContent, list);

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