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

#include <cstddef>
#include <sstream>
#include <utility>

#include "cmCPackIFWCommon.h"
#include "cmCPackIFWGenerator.h"
#include "cmCPackIFWPackage.h"
#include "cmCPackIFWRepository.h"
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmGeneratedFileStream.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmXMLWriter.h"

cmCPackIFWInstaller::cmCPackIFWInstaller() = default;

void cmCPackIFWInstaller::printSkippedOptionWarning(
  const std::string& optionName, const std::string& optionValue)
{
  cmCPackIFWLogger(
    WARNING,
    "Option "
      << optionName << " is set to \"" << optionValue
      << "\" but will be skipped because the specified file does not exist."
      << std::endl);
}

void cmCPackIFWInstaller::ConfigureFromOptions()
{
  // Name;
  if (const char* optIFW_PACKAGE_NAME =
        this->GetOption("CPACK_IFW_PACKAGE_NAME")) {
    this->Name = optIFW_PACKAGE_NAME;
  } else if (const char* optPACKAGE_NAME =
               this->GetOption("CPACK_PACKAGE_NAME")) {
    this->Name = optPACKAGE_NAME;
  } else {
    this->Name = "Your package";
  }

  // Title;
  if (const char* optIFW_PACKAGE_TITLE =
        this->GetOption("CPACK_IFW_PACKAGE_TITLE")) {
    this->Title = optIFW_PACKAGE_TITLE;
  } else if (const char* optPACKAGE_DESCRIPTION_SUMMARY =
               this->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY")) {
    this->Title = optPACKAGE_DESCRIPTION_SUMMARY;
  } else {
    this->Title = "Your package description";
  }

  // Version;
  if (const char* option = this->GetOption("CPACK_PACKAGE_VERSION")) {
    this->Version = option;
  } else {
    this->Version = "1.0.0";
  }

  // Publisher
  if (const char* optIFW_PACKAGE_PUBLISHER =
        this->GetOption("CPACK_IFW_PACKAGE_PUBLISHER")) {
    this->Publisher = optIFW_PACKAGE_PUBLISHER;
  } else if (const char* optPACKAGE_VENDOR =
               GetOption("CPACK_PACKAGE_VENDOR")) {
    this->Publisher = optPACKAGE_VENDOR;
  }

  // ProductUrl
  if (const char* option = this->GetOption("CPACK_IFW_PRODUCT_URL")) {
    this->ProductUrl = option;
  }

  // ApplicationIcon
  if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_ICON")) {
    if (cmSystemTools::FileExists(option)) {
      this->InstallerApplicationIcon = option;
    } else {
      this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_ICON", option);
    }
  }

  // WindowIcon
  if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_WINDOW_ICON")) {
    if (cmSystemTools::FileExists(option)) {
      this->InstallerWindowIcon = option;
    } else {
      this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_WINDOW_ICON", option);
    }
  }

  // RemoveTargetDir
  if (this->IsSetToOff("CPACK_IFW_PACKAGE_REMOVE_TARGET_DIR")) {
    this->RemoveTargetDir = "false";
  } else if (this->IsOn("CPACK_IFW_PACKAGE_REMOVE_TARGET_DIR")) {
    this->RemoveTargetDir = "true";
  } else {
    this->RemoveTargetDir.clear();
  }

  // Logo
  if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_LOGO")) {
    if (cmSystemTools::FileExists(option)) {
      this->Logo = option;
    } else {
      this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_LOGO", option);
    }
  }

  // Watermark
  if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_WATERMARK")) {
    if (cmSystemTools::FileExists(option)) {
      this->Watermark = option;
    } else {
      this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_WATERMARK", option);
    }
  }

  // Banner
  if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_BANNER")) {
    if (cmSystemTools::FileExists(option)) {
      this->Banner = option;
    } else {
      this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_BANNER", option);
    }
  }

  // Background
  if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_BACKGROUND")) {
    if (cmSystemTools::FileExists(option)) {
      this->Background = option;
    } else {
      this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_BACKGROUND", option);
    }
  }

  // WizardStyle
  if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_WIZARD_STYLE")) {
    // Setting the user value in any case
    this->WizardStyle = option;
    // Check known values
    if (this->WizardStyle != "Modern" && this->WizardStyle != "Aero" &&
        this->WizardStyle != "Mac" && this->WizardStyle != "Classic") {
      cmCPackIFWLogger(
        WARNING,
        "Option CPACK_IFW_PACKAGE_WIZARD_STYLE has unknown value \""
          << option << "\". Expected values are: Modern, Aero, Mac, Classic."
          << std::endl);
    }
  }

  // StyleSheet
  if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_STYLE_SHEET")) {
    if (cmSystemTools::FileExists(option)) {
      this->StyleSheet = option;
    } else {
      this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_STYLE_SHEET", option);
    }
  }

  // WizardDefaultWidth
  if (const char* option =
        this->GetOption("CPACK_IFW_PACKAGE_WIZARD_DEFAULT_WIDTH")) {
    this->WizardDefaultWidth = option;
  }

  // WizardDefaultHeight
  if (const char* option =
        this->GetOption("CPACK_IFW_PACKAGE_WIZARD_DEFAULT_HEIGHT")) {
    this->WizardDefaultHeight = option;
  }

  // TitleColor
  if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_TITLE_COLOR")) {
    this->TitleColor = option;
  }

  // Start menu
  if (const char* optIFW_START_MENU_DIR =
        this->GetOption("CPACK_IFW_PACKAGE_START_MENU_DIRECTORY")) {
    this->StartMenuDir = optIFW_START_MENU_DIR;
  } else {
    this->StartMenuDir = Name;
  }

  // Default target directory for installation
  if (const char* optIFW_TARGET_DIRECTORY =
        this->GetOption("CPACK_IFW_TARGET_DIRECTORY")) {
    this->TargetDir = optIFW_TARGET_DIRECTORY;
  } else if (const char* optPACKAGE_INSTALL_DIRECTORY =
               this->GetOption("CPACK_PACKAGE_INSTALL_DIRECTORY")) {
    this->TargetDir =
      cmStrCat("@ApplicationsDir@/", optPACKAGE_INSTALL_DIRECTORY);
  } else {
    this->TargetDir = "@RootDir@/usr/local";
  }

  // Default target directory for installation with administrator rights
  if (const char* option =
        this->GetOption("CPACK_IFW_ADMIN_TARGET_DIRECTORY")) {
    this->AdminTargetDir = option;
  }

  // Maintenance tool
  if (const char* optIFW_MAINTENANCE_TOOL =
        this->GetOption("CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_NAME")) {
    this->MaintenanceToolName = optIFW_MAINTENANCE_TOOL;
  }

  // Maintenance tool ini file
  if (const char* optIFW_MAINTENANCE_TOOL_INI =
        this->GetOption("CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_INI_FILE")) {
    this->MaintenanceToolIniFile = optIFW_MAINTENANCE_TOOL_INI;
  }

  // Allow non-ASCII characters
  if (this->GetOption("CPACK_IFW_PACKAGE_ALLOW_NON_ASCII_CHARACTERS")) {
    if (this->IsOn("CPACK_IFW_PACKAGE_ALLOW_NON_ASCII_CHARACTERS")) {
      this->AllowNonAsciiCharacters = "true";
    } else {
      this->AllowNonAsciiCharacters = "false";
    }
  }

  // Space in path
  if (this->GetOption("CPACK_IFW_PACKAGE_ALLOW_SPACE_IN_PATH")) {
    if (this->IsOn("CPACK_IFW_PACKAGE_ALLOW_SPACE_IN_PATH")) {
      this->AllowSpaceInPath = "true";
    } else {
      this->AllowSpaceInPath = "false";
    }
  }

  // Control script
  if (const char* optIFW_CONTROL_SCRIPT =
        this->GetOption("CPACK_IFW_PACKAGE_CONTROL_SCRIPT")) {
    this->ControlScript = optIFW_CONTROL_SCRIPT;
  }

  // Resources
  if (const char* optIFW_PACKAGE_RESOURCES =
        this->GetOption("CPACK_IFW_PACKAGE_RESOURCES")) {
    this->Resources.clear();
    cmExpandList(optIFW_PACKAGE_RESOURCES, this->Resources);
  }
}

/** \class cmCPackIFWResourcesParser
 * \brief Helper class that parse resources form .qrc (Qt)
 */
class cmCPackIFWResourcesParser : public cmXMLParser
{
public:
  cmCPackIFWResourcesParser(cmCPackIFWInstaller* i)
    : installer(i)
    , file(false)
  {
    this->path = i->Directory + "/resources";
  }

  bool ParseResource(size_t r)
  {
    this->hasFiles = false;
    this->hasErrors = false;

    this->basePath =
      cmSystemTools::GetFilenamePath(this->installer->Resources[r]);

    this->ParseFile(this->installer->Resources[r].data());

    return this->hasFiles && !this->hasErrors;
  }

  cmCPackIFWInstaller* installer;
  bool file, hasFiles, hasErrors;
  std::string path, basePath;

protected:
  void StartElement(const std::string& name, const char** /*atts*/) override
  {
    this->file = name == "file";
    if (file) {
      this->hasFiles = true;
    }
  }

  void CharacterDataHandler(const char* data, int length) override
  {
    if (this->file) {
      std::string content(data, data + length);
      content = cmTrimWhitespace(content);
      std::string source = this->basePath + "/" + content;
      std::string destination = this->path + "/" + content;
      if (!cmSystemTools::CopyFileIfDifferent(source, destination)) {
        this->hasErrors = true;
      }
    }
  }

  void EndElement(const std::string& /*name*/) override {}
};

void cmCPackIFWInstaller::GenerateInstallerFile()
{
  // Lazy directory initialization
  if (this->Directory.empty() && this->Generator) {
    this->Directory = this->Generator->toplevel;
  }

  // Output stream
  cmGeneratedFileStream fout(this->Directory + "/config/config.xml");
  cmXMLWriter xout(fout);

  xout.StartDocument();

  WriteGeneratedByToStrim(xout);

  xout.StartElement("Installer");

  xout.Element("Name", this->Name);
  xout.Element("Version", this->Version);
  xout.Element("Title", this->Title);

  if (!this->Publisher.empty()) {
    xout.Element("Publisher", this->Publisher);
  }

  if (!this->ProductUrl.empty()) {
    xout.Element("ProductUrl", this->ProductUrl);
  }

  // ApplicationIcon
  if (!this->InstallerApplicationIcon.empty()) {
    std::string name =
      cmSystemTools::GetFilenameName(this->InstallerApplicationIcon);
    std::string path = this->Directory + "/config/" + name;
    name = cmSystemTools::GetFilenameWithoutExtension(name);
    cmsys::SystemTools::CopyFileIfDifferent(this->InstallerApplicationIcon,
                                            path);
    xout.Element("InstallerApplicationIcon", name);
  }

  // WindowIcon
  if (!this->InstallerWindowIcon.empty()) {
    std::string name =
      cmSystemTools::GetFilenameName(this->InstallerWindowIcon);
    std::string path = this->Directory + "/config/" + name;
    cmsys::SystemTools::CopyFileIfDifferent(this->InstallerWindowIcon, path);
    xout.Element("InstallerWindowIcon", name);
  }

  // Logo
  if (!this->Logo.empty()) {
    std::string name = cmSystemTools::GetFilenameName(this->Logo);
    std::string path = this->Directory + "/config/" + name;
    cmsys::SystemTools::CopyFileIfDifferent(this->Logo, path);
    xout.Element("Logo", name);
  }

  // Banner
  if (!this->Banner.empty()) {
    std::string name = cmSystemTools::GetFilenameName(this->Banner);
    std::string path = this->Directory + "/config/" + name;
    cmsys::SystemTools::CopyFileIfDifferent(this->Banner, path);
    xout.Element("Banner", name);
  }

  // Watermark
  if (!this->Watermark.empty()) {
    std::string name = cmSystemTools::GetFilenameName(this->Watermark);
    std::string path = this->Directory + "/config/" + name;
    cmsys::SystemTools::CopyFileIfDifferent(this->Watermark, path);
    xout.Element("Watermark", name);
  }

  // Background
  if (!this->Background.empty()) {
    std::string name = cmSystemTools::GetFilenameName(this->Background);
    std::string path = this->Directory + "/config/" + name;
    cmsys::SystemTools::CopyFileIfDifferent(this->Background, path);
    xout.Element("Background", name);
  }

  // WizardStyle
  if (!this->WizardStyle.empty()) {
    xout.Element("WizardStyle", this->WizardStyle);
  }

  // Stylesheet
  if (!this->StyleSheet.empty()) {
    std::string name = cmSystemTools::GetFilenameName(this->StyleSheet);
    std::string path = this->Directory + "/config/" + name;
    cmsys::SystemTools::CopyFileIfDifferent(this->StyleSheet, path);
    xout.Element("StyleSheet", name);
  }

  // WizardDefaultWidth
  if (!this->WizardDefaultWidth.empty()) {
    xout.Element("WizardDefaultWidth", this->WizardDefaultWidth);
  }

  // WizardDefaultHeight
  if (!this->WizardDefaultHeight.empty()) {
    xout.Element("WizardDefaultHeight", this->WizardDefaultHeight);
  }

  // TitleColor
  if (!this->TitleColor.empty()) {
    xout.Element("TitleColor", this->TitleColor);
  }

  // Start menu
  if (!this->IsVersionLess("2.0")) {
    xout.Element("StartMenuDir", this->StartMenuDir);
  }

  // Target dir
  if (!this->TargetDir.empty()) {
    xout.Element("TargetDir", this->TargetDir);
  }

  // Admin target dir
  if (!this->AdminTargetDir.empty()) {
    xout.Element("AdminTargetDir", this->AdminTargetDir);
  }

  // Remote repositories
  if (!this->RemoteRepositories.empty()) {
    xout.StartElement("RemoteRepositories");
    for (cmCPackIFWRepository* r : this->RemoteRepositories) {
      r->WriteRepositoryConfig(xout);
    }
    xout.EndElement();
  }

  // Maintenance tool
  if (!this->IsVersionLess("2.0") && !this->MaintenanceToolName.empty()) {
    xout.Element("MaintenanceToolName", this->MaintenanceToolName);
  }

  // Maintenance tool ini file
  if (!this->IsVersionLess("2.0") && !this->MaintenanceToolIniFile.empty()) {
    xout.Element("MaintenanceToolIniFile", this->MaintenanceToolIniFile);
  }

  if (!this->RemoveTargetDir.empty()) {
    xout.Element("RemoveTargetDir", this->RemoveTargetDir);
  }

  // Different allows
  if (this->IsVersionLess("2.0")) {
    // CPack IFW default policy
    xout.Comment("CPack IFW default policy for QtIFW less 2.0");
    xout.Element("AllowNonAsciiCharacters", "true");
    xout.Element("AllowSpaceInPath", "true");
  } else {
    if (!this->AllowNonAsciiCharacters.empty()) {
      xout.Element("AllowNonAsciiCharacters", this->AllowNonAsciiCharacters);
    }
    if (!this->AllowSpaceInPath.empty()) {
      xout.Element("AllowSpaceInPath", this->AllowSpaceInPath);
    }
  }

  // Control script (copy to config dir)
  if (!this->IsVersionLess("2.0") && !this->ControlScript.empty()) {
    std::string name = cmSystemTools::GetFilenameName(this->ControlScript);
    std::string path = this->Directory + "/config/" + name;
    cmsys::SystemTools::CopyFileIfDifferent(this->ControlScript, path);
    xout.Element("ControlScript", name);
  }

  // Resources (copy to resources dir)
  if (!this->Resources.empty()) {
    std::vector<std::string> resources;
    cmCPackIFWResourcesParser parser(this);
    for (size_t i = 0; i < this->Resources.size(); i++) {
      if (parser.ParseResource(i)) {
        std::string name = cmSystemTools::GetFilenameName(this->Resources[i]);
        std::string path = this->Directory + "/resources/" + name;
        cmsys::SystemTools::CopyFileIfDifferent(this->Resources[i], path);
        resources.push_back(std::move(name));
      } else {
        cmCPackIFWLogger(WARNING,
                         "Can't copy resources from \""
                           << this->Resources[i]
                           << "\". Resource will be skipped." << std::endl);
      }
    }
    this->Resources = resources;
  }

  xout.EndElement();
  xout.EndDocument();
}

void cmCPackIFWInstaller::GeneratePackageFiles()
{
  if (this->Packages.empty() || this->Generator->IsOnePackage()) {
    // Generate default package
    cmCPackIFWPackage package;
    package.Generator = this->Generator;
    package.Installer = this;
    // Check package group
    if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_GROUP")) {
      package.ConfigureFromGroup(option);
      std::string forcedOption = "CPACK_IFW_COMPONENT_GROUP_" +
        cmsys::SystemTools::UpperCase(option) + "_FORCED_INSTALLATION";
      if (!GetOption(forcedOption)) {
        package.ForcedInstallation = "true";
      }
    } else {
      package.ConfigureFromOptions();
    }
    package.GeneratePackageFile();
    return;
  }

  // Generate packages meta information
  for (auto& p : this->Packages) {
    cmCPackIFWPackage* package = p.second;
    package->GeneratePackageFile();
  }
}
