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

#include "cmCPackComponentGroup.h"
#include "cmCPackIFWCommon.h"
#include "cmCPackIFWGenerator.h"
#include "cmCPackIFWInstaller.h"
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmGeneratedFileStream.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmXMLWriter.h"

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

//---------------------------------------------------------- CompareStruct ---
cmCPackIFWPackage::CompareStruct::CompareStruct()
  : Type(cmCPackIFWPackage::CompareNone)
{
}

//------------------------------------------------------- DependenceStruct ---
cmCPackIFWPackage::DependenceStruct::DependenceStruct() = default;

cmCPackIFWPackage::DependenceStruct::DependenceStruct(
  const std::string& dependence)
{
  // Search compare section
  size_t pos = std::string::npos;
  if ((pos = dependence.find("<=")) != std::string::npos) {
    this->Compare.Type = cmCPackIFWPackage::CompareLessOrEqual;
    this->Compare.Value = dependence.substr(pos + 2);
  } else if ((pos = dependence.find(">=")) != std::string::npos) {
    this->Compare.Type = cmCPackIFWPackage::CompareGreaterOrEqual;
    this->Compare.Value = dependence.substr(pos + 2);
  } else if ((pos = dependence.find('<')) != std::string::npos) {
    this->Compare.Type = cmCPackIFWPackage::CompareLess;
    this->Compare.Value = dependence.substr(pos + 1);
  } else if ((pos = dependence.find('=')) != std::string::npos) {
    this->Compare.Type = cmCPackIFWPackage::CompareEqual;
    this->Compare.Value = dependence.substr(pos + 1);
  } else if ((pos = dependence.find('>')) != std::string::npos) {
    this->Compare.Type = cmCPackIFWPackage::CompareGreater;
    this->Compare.Value = dependence.substr(pos + 1);
  } else if ((pos = dependence.find('-')) != std::string::npos) {
    this->Compare.Type = cmCPackIFWPackage::CompareNone;
    this->Compare.Value = dependence.substr(pos + 1);
  }
  size_t dashPos = dependence.find('-');
  if (dashPos != std::string::npos) {
    pos = dashPos;
  }
  this->Name =
    pos == std::string::npos ? dependence : dependence.substr(0, pos);
}

std::string cmCPackIFWPackage::DependenceStruct::NameWithCompare() const
{
  if (this->Compare.Type == cmCPackIFWPackage::CompareNone) {
    return this->Name;
  }

  std::string result = this->Name;

  if (this->Compare.Type != cmCPackIFWPackage::CompareNone ||
      !this->Compare.Value.empty()) {
    result += "-";
  }

  if (this->Compare.Type == cmCPackIFWPackage::CompareLessOrEqual) {
    result += "<=";
  } else if (this->Compare.Type == cmCPackIFWPackage::CompareGreaterOrEqual) {
    result += ">=";
  } else if (this->Compare.Type == cmCPackIFWPackage::CompareLess) {
    result += "<";
  } else if (this->Compare.Type == cmCPackIFWPackage::CompareEqual) {
    result += "=";
  } else if (this->Compare.Type == cmCPackIFWPackage::CompareGreater) {
    result += ">";
  }

  result += this->Compare.Value;

  return result;
}

//------------------------------------------------------ cmCPackIFWPackage ---
cmCPackIFWPackage::cmCPackIFWPackage()
  : Installer(nullptr)
{
}

std::string cmCPackIFWPackage::GetComponentName(cmCPackComponent* component)
{
  if (!component) {
    return "";
  }
  const char* option =
    this->GetOption("CPACK_IFW_COMPONENT_" +
                    cmsys::SystemTools::UpperCase(component->Name) + "_NAME");
  return option ? option : component->Name;
}

void cmCPackIFWPackage::DefaultConfiguration()
{
  this->DisplayName.clear();
  this->Description.clear();
  this->Version.clear();
  this->ReleaseDate.clear();
  this->Script.clear();
  this->Licenses.clear();
  this->UserInterfaces.clear();
  this->Translations.clear();
  this->SortingPriority.clear();
  this->UpdateText.clear();
  this->Default.clear();
  this->Essential.clear();
  this->Virtual.clear();
  this->ForcedInstallation.clear();
  this->RequiresAdminRights.clear();
}

// Default configuration (all in one package)
int cmCPackIFWPackage::ConfigureFromOptions()
{
  // Restore default configuration
  this->DefaultConfiguration();

  // Name
  this->Name = this->Generator->GetRootPackageName();

  // Display name
  if (const char* option = this->GetOption("CPACK_PACKAGE_NAME")) {
    this->DisplayName[""] = option;
  } else {
    this->DisplayName[""] = "Your package";
  }

  // Description
  if (const char* option =
        this->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY")) {
    this->Description[""] = option;
  } else {
    this->Description[""] = "Your package description";
  }

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

  this->ForcedInstallation = "true";

  return 1;
}

int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component)
{
  if (!component) {
    return 0;
  }

  // Restore default configuration
  this->DefaultConfiguration();

  std::string prefix = "CPACK_IFW_COMPONENT_" +
    cmsys::SystemTools::UpperCase(component->Name) + "_";

  // Display name
  this->DisplayName[""] = component->DisplayName;

  // Description
  this->Description[""] = component->Description;

  // Version
  if (const char* optVERSION = this->GetOption(prefix + "VERSION")) {
    this->Version = optVERSION;
  } else if (const char* optPACKAGE_VERSION =
               this->GetOption("CPACK_PACKAGE_VERSION")) {
    this->Version = optPACKAGE_VERSION;
  } else {
    this->Version = "1.0.0";
  }

  // Script
  if (const char* option = this->GetOption(prefix + "SCRIPT")) {
    this->Script = option;
  }

  // User interfaces
  if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) {
    this->UserInterfaces.clear();
    cmSystemTools::ExpandListArgument(option, this->UserInterfaces);
  }

  // CMake dependencies
  if (!component->Dependencies.empty()) {
    for (cmCPackComponent* dep : component->Dependencies) {
      this->Dependencies.insert(this->Generator->ComponentPackages[dep]);
    }
  }

  // Licenses
  if (const char* option = this->GetOption(prefix + "LICENSES")) {
    this->Licenses.clear();
    cmSystemTools::ExpandListArgument(option, this->Licenses);
    if (this->Licenses.size() % 2 != 0) {
      cmCPackIFWLogger(
        WARNING,
        prefix << "LICENSES"
               << " should contain pairs of <display_name> and <file_path>."
               << std::endl);
      this->Licenses.clear();
    }
  }

  // Priority
  if (const char* option = this->GetOption(prefix + "PRIORITY")) {
    this->SortingPriority = option;
    cmCPackIFWLogger(
      WARNING,
      "The \"PRIORITY\" option is set "
        << "for component \"" << component->Name << "\", but there option is "
        << "deprecated. Please use \"SORTING_PRIORITY\" option instead."
        << std::endl);
  }

  // Default
  this->Default = component->IsDisabledByDefault ? "false" : "true";

  // Essential
  if (this->IsOn(prefix + "ESSENTIAL")) {
    this->Essential = "true";
  }

  // Virtual
  this->Virtual = component->IsHidden ? "true" : "";

  // ForcedInstallation
  this->ForcedInstallation = component->IsRequired ? "true" : "false";

  return this->ConfigureFromPrefix(prefix);
}

int cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup* group)
{
  if (!group) {
    return 0;
  }

  // Restore default configuration
  this->DefaultConfiguration();

  std::string prefix = "CPACK_IFW_COMPONENT_GROUP_" +
    cmsys::SystemTools::UpperCase(group->Name) + "_";

  this->DisplayName[""] = group->DisplayName;
  this->Description[""] = group->Description;

  // Version
  if (const char* optVERSION = this->GetOption(prefix + "VERSION")) {
    this->Version = optVERSION;
  } else if (const char* optPACKAGE_VERSION =
               this->GetOption("CPACK_PACKAGE_VERSION")) {
    this->Version = optPACKAGE_VERSION;
  } else {
    this->Version = "1.0.0";
  }

  // Script
  if (const char* option = this->GetOption(prefix + "SCRIPT")) {
    this->Script = option;
  }

  // User interfaces
  if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) {
    this->UserInterfaces.clear();
    cmSystemTools::ExpandListArgument(option, this->UserInterfaces);
  }

  // Licenses
  if (const char* option = this->GetOption(prefix + "LICENSES")) {
    this->Licenses.clear();
    cmSystemTools::ExpandListArgument(option, this->Licenses);
    if (this->Licenses.size() % 2 != 0) {
      cmCPackIFWLogger(
        WARNING,
        prefix << "LICENSES"
               << " should contain pairs of <display_name> and <file_path>."
               << std::endl);
      this->Licenses.clear();
    }
  }

  // Priority
  if (const char* option = this->GetOption(prefix + "PRIORITY")) {
    this->SortingPriority = option;
    cmCPackIFWLogger(
      WARNING,
      "The \"PRIORITY\" option is set "
        << "for component group \"" << group->Name
        << "\", but there option is "
        << "deprecated. Please use \"SORTING_PRIORITY\" option instead."
        << std::endl);
  }

  return this->ConfigureFromPrefix(prefix);
}

int cmCPackIFWPackage::ConfigureFromGroup(const std::string& groupName)
{
  // Group configuration

  cmCPackComponentGroup group;
  std::string prefix =
    "CPACK_COMPONENT_GROUP_" + cmsys::SystemTools::UpperCase(groupName) + "_";

  if (const char* option = this->GetOption(prefix + "DISPLAY_NAME")) {
    group.DisplayName = option;
  } else {
    group.DisplayName = group.Name;
  }

  if (const char* option = this->GetOption(prefix + "DESCRIPTION")) {
    group.Description = option;
  }
  group.IsBold = this->IsOn(prefix + "BOLD_TITLE");
  group.IsExpandedByDefault = this->IsOn(prefix + "EXPANDED");

  // Package configuration

  group.Name = groupName;

  if (Generator) {
    this->Name = this->Generator->GetGroupPackageName(&group);
  } else {
    this->Name = group.Name;
  }

  return this->ConfigureFromGroup(&group);
}

// Common options for components and groups
int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix)
{
  // Temporary variable for full option name
  std::string option;

  // Display name
  option = prefix + "DISPLAY_NAME";
  if (this->IsSetToEmpty(option)) {
    this->DisplayName.clear();
  } else if (const char* value = this->GetOption(option)) {
    cmCPackIFWPackage::ExpandListArgument(value, this->DisplayName);
  }

  // Description
  option = prefix + "DESCRIPTION";
  if (this->IsSetToEmpty(option)) {
    this->Description.clear();
  } else if (const char* value = this->GetOption(option)) {
    cmCPackIFWPackage::ExpandListArgument(value, this->Description);
  }

  // Release date
  option = prefix + "RELEASE_DATE";
  if (this->IsSetToEmpty(option)) {
    this->ReleaseDate.clear();
  } else if (const char* value = this->GetOption(option)) {
    this->ReleaseDate = value;
  }

  // Sorting priority
  option = prefix + "SORTING_PRIORITY";
  if (this->IsSetToEmpty(option)) {
    this->SortingPriority.clear();
  } else if (const char* value = this->GetOption(option)) {
    this->SortingPriority = value;
  }

  // Update text
  option = prefix + "UPDATE_TEXT";
  if (this->IsSetToEmpty(option)) {
    this->UpdateText.clear();
  } else if (const char* value = this->GetOption(option)) {
    this->UpdateText = value;
  }

  // Translations
  option = prefix + "TRANSLATIONS";
  if (this->IsSetToEmpty(option)) {
    this->Translations.clear();
  } else if (const char* value = this->GetOption(option)) {
    this->Translations.clear();
    cmSystemTools::ExpandListArgument(value, this->Translations);
  }

  // QtIFW dependencies
  std::vector<std::string> deps;
  option = prefix + "DEPENDS";
  if (const char* value = this->GetOption(option)) {
    cmSystemTools::ExpandListArgument(value, deps);
  }
  option = prefix + "DEPENDENCIES";
  if (const char* value = this->GetOption(option)) {
    cmSystemTools::ExpandListArgument(value, deps);
  }
  for (std::string const& d : deps) {
    DependenceStruct dep(d);
    if (this->Generator->Packages.count(dep.Name)) {
      cmCPackIFWPackage& depPkg = this->Generator->Packages[dep.Name];
      dep.Name = depPkg.Name;
    }
    bool hasDep = this->Generator->DependentPackages.count(dep.Name) > 0;
    DependenceStruct& depRef = this->Generator->DependentPackages[dep.Name];
    if (!hasDep) {
      depRef = dep;
    }
    this->AlienDependencies.insert(&depRef);
  }

  // Automatic dependency on
  option = prefix + "AUTO_DEPEND_ON";
  if (this->IsSetToEmpty(option)) {
    this->AlienAutoDependOn.clear();
  } else if (const char* value = this->GetOption(option)) {
    std::vector<std::string> depsOn;
    cmSystemTools::ExpandListArgument(value, depsOn);
    for (std::string const& d : depsOn) {
      DependenceStruct dep(d);
      if (this->Generator->Packages.count(dep.Name)) {
        cmCPackIFWPackage& depPkg = this->Generator->Packages[dep.Name];
        dep.Name = depPkg.Name;
      }
      bool hasDep = this->Generator->DependentPackages.count(dep.Name) > 0;
      DependenceStruct& depRef = this->Generator->DependentPackages[dep.Name];
      if (!hasDep) {
        depRef = dep;
      }
      this->AlienAutoDependOn.insert(&depRef);
    }
  }

  // Visibility
  option = prefix + "VIRTUAL";
  if (this->IsSetToEmpty(option)) {
    this->Virtual.clear();
  } else if (this->IsOn(option)) {
    this->Virtual = "true";
  }

  // Default selection
  option = prefix + "DEFAULT";
  if (this->IsSetToEmpty(option)) {
    this->Default.clear();
  } else if (const char* value = this->GetOption(option)) {
    std::string lowerValue = cmsys::SystemTools::LowerCase(value);
    if (lowerValue == "true") {
      this->Default = "true";
    } else if (lowerValue == "false") {
      this->Default = "false";
    } else if (lowerValue == "script") {
      this->Default = "script";
    } else {
      this->Default = value;
    }
  }

  // Forsed installation
  option = prefix + "FORCED_INSTALLATION";
  if (this->IsSetToEmpty(option)) {
    this->ForcedInstallation.clear();
  } else if (this->IsOn(option)) {
    this->ForcedInstallation = "true";
  } else if (this->IsSetToOff(option)) {
    this->ForcedInstallation = "false";
  }

  // Replaces
  option = prefix + "REPLACES";
  if (this->IsSetToEmpty(option)) {
    this->Replaces.clear();
  } else if (const char* value = this->GetOption(option)) {
    this->Replaces.clear();
    cmSystemTools::ExpandListArgument(value, this->Replaces);
  }

  // Requires admin rights
  option = prefix + "REQUIRES_ADMIN_RIGHTS";
  if (this->IsSetToEmpty(option)) {
    this->RequiresAdminRights.clear();
  } else if (this->IsOn(option)) {
    this->RequiresAdminRights = "true";
  } else if (this->IsSetToOff(option)) {
    this->RequiresAdminRights = "false";
  }

  // Checkable
  option = prefix + "CHECKABLE";
  if (this->IsSetToEmpty(option)) {
    this->Checkable.clear();
  } else if (this->IsOn(option)) {
    this->Checkable = "true";
  } else if (this->IsSetToOff(option)) {
    this->Checkable = "false";
  }

  return 1;
}

void cmCPackIFWPackage::GeneratePackageFile()
{
  // Lazy directory initialization
  if (this->Directory.empty()) {
    if (this->Installer) {
      this->Directory = this->Installer->Directory + "/packages/" + this->Name;
    } else if (this->Generator) {
      this->Directory = this->Generator->toplevel + "/packages/" + this->Name;
    }
  }

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

  xout.StartDocument();

  WriteGeneratedByToStrim(xout);

  xout.StartElement("Package");

  // DisplayName (with translations)
  for (auto const& dn : this->DisplayName) {
    xout.StartElement("DisplayName");
    if (!dn.first.empty()) {
      xout.Attribute("xml:lang", dn.first);
    }
    xout.Content(dn.second);
    xout.EndElement();
  }

  // Description (with translations)
  for (auto const& d : this->Description) {
    xout.StartElement("Description");
    if (!d.first.empty()) {
      xout.Attribute("xml:lang", d.first);
    }
    xout.Content(d.second);
    xout.EndElement();
  }

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

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

  if (!this->ReleaseDate.empty()) {
    xout.Element("ReleaseDate", this->ReleaseDate);
  } else {
    xout.Element("ReleaseDate", cmTimestamp().CurrentTime("%Y-%m-%d", true));
  }

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

  // User Interfaces (copy to meta dir)
  std::vector<std::string> userInterfaces = UserInterfaces;
  for (std::string& userInterface : userInterfaces) {
    std::string name = cmSystemTools::GetFilenameName(userInterface);
    std::string path = this->Directory + "/meta/" + name;
    cmsys::SystemTools::CopyFileIfDifferent(userInterface, path);
    userInterface = name;
  }
  if (!userInterfaces.empty()) {
    xout.StartElement("UserInterfaces");
    for (std::string const& userInterface : userInterfaces) {
      xout.Element("UserInterface", userInterface);
    }
    xout.EndElement();
  }

  // Translations (copy to meta dir)
  std::vector<std::string> translations = Translations;
  for (std::string& translation : translations) {
    std::string name = cmSystemTools::GetFilenameName(translation);
    std::string path = this->Directory + "/meta/" + name;
    cmsys::SystemTools::CopyFileIfDifferent(translation, path);
    translation = name;
  }
  if (!translations.empty()) {
    xout.StartElement("Translations");
    for (std::string const& translation : translations) {
      xout.Element("Translation", translation);
    }
    xout.EndElement();
  }

  // Dependencies
  std::set<DependenceStruct> compDepSet;
  for (DependenceStruct* ad : this->AlienDependencies) {
    compDepSet.insert(*ad);
  }
  for (cmCPackIFWPackage* d : this->Dependencies) {
    compDepSet.insert(DependenceStruct(d->Name));
  }
  // Write dependencies
  if (!compDepSet.empty()) {
    std::ostringstream dependencies;
    std::set<DependenceStruct>::iterator it = compDepSet.begin();
    dependencies << it->NameWithCompare();
    ++it;
    while (it != compDepSet.end()) {
      dependencies << "," << it->NameWithCompare();
      ++it;
    }
    xout.Element("Dependencies", dependencies.str());
  }

  // Automatic dependency on
  std::set<DependenceStruct> compAutoDepSet;
  for (DependenceStruct* aad : this->AlienAutoDependOn) {
    compAutoDepSet.insert(*aad);
  }
  // Write automatic dependency on
  if (!compAutoDepSet.empty()) {
    std::ostringstream dependencies;
    std::set<DependenceStruct>::iterator it = compAutoDepSet.begin();
    dependencies << it->NameWithCompare();
    ++it;
    while (it != compAutoDepSet.end()) {
      dependencies << "," << it->NameWithCompare();
      ++it;
    }
    xout.Element("AutoDependOn", dependencies.str());
  }

  // Licenses (copy to meta dir)
  std::vector<std::string> licenses = this->Licenses;
  for (size_t i = 1; i < licenses.size(); i += 2) {
    std::string name = cmSystemTools::GetFilenameName(licenses[i]);
    std::string path = this->Directory + "/meta/" + name;
    cmsys::SystemTools::CopyFileIfDifferent(licenses[i], path);
    licenses[i] = name;
  }
  if (!licenses.empty()) {
    xout.StartElement("Licenses");
    for (size_t i = 0; i < licenses.size(); i += 2) {
      xout.StartElement("License");
      xout.Attribute("name", licenses[i]);
      xout.Attribute("file", licenses[i + 1]);
      xout.EndElement();
    }
    xout.EndElement();
  }

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

  // Replaces
  if (!this->Replaces.empty()) {
    std::ostringstream replaces;
    std::vector<std::string>::iterator it = this->Replaces.begin();
    replaces << *it;
    ++it;
    while (it != this->Replaces.end()) {
      replaces << "," << *it;
      ++it;
    }
    xout.Element("Replaces", replaces.str());
  }

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

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

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

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

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

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