/* 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 "cmCPackIFWCommon.h"
#include "cmCPackIFWGenerator.h"
#include "cmCPackIFWPackage.h"
#include "cmCPackIFWRepository.h"
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmGeneratedFileStream.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmXMLWriter.h"

#include <sstream>
#include <stddef.h>
#include <utility>

cmCPackIFWInstaller::cmCPackIFWInstaller()
{
}

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

  // 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 = "@ApplicationsDir@/";
    this->TargetDir += 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();
    cmSystemTools::ExpandListArgument(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 = cmSystemTools::TrimWhitespace(content);
      std::string source = this->basePath + "/" + content;
      std::string destination = this->path + "/" + content;
      if (!cmSystemTools::CopyFileIfDifferent(source.data(),
                                              destination.data())) {
        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);
  }

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