/* 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 <cstddef>
#include <map>
#include <sstream>
#include <utility>

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

//---------------------------------------------------------- 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();
    cmExpandList(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();
    cmExpandList(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();
    cmExpandList(option, this->UserInterfaces);
  }

  // Licenses
  if (const char* option = this->GetOption(prefix + "LICENSES")) {
    this->Licenses.clear();
    cmExpandList(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();
    cmExpandList(value, this->Translations);
  }

  // QtIFW dependencies
  std::vector<std::string> deps;
  option = prefix + "DEPENDS";
  if (const char* value = this->GetOption(option)) {
    cmExpandList(value, deps);
  }
  option = prefix + "DEPENDENCIES";
  if (const char* value = this->GetOption(option)) {
    cmExpandList(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 = cmExpandedList(value);
    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();
    cmExpandList(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;
    auto 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;
    auto 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;
    auto 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();
}
