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

#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackIFWCommon.h"
#include "cmCPackIFWInstaller.h"
#include "cmCPackIFWPackage.h"
#include "cmCPackIFWRepository.h"
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
#include "cmSystemTools.h"

#include <sstream>
#include <utility>

cmCPackIFWGenerator::cmCPackIFWGenerator()
{
  this->Generator = this;
}

cmCPackIFWGenerator::~cmCPackIFWGenerator()
{
}

int cmCPackIFWGenerator::PackageFiles()
{
  cmCPackIFWLogger(OUTPUT, "- Configuration" << std::endl);

  // Installer configuragion
  this->Installer.GenerateInstallerFile();

  // Packages configuration
  this->Installer.GeneratePackageFiles();

  std::string ifwTLD = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  std::string ifwTmpFile = ifwTLD;
  ifwTmpFile += "/IFWOutput.log";

  // Run repogen
  if (!this->Installer.RemoteRepositories.empty()) {
    std::string ifwCmd = this->RepoGen;

    if (this->IsVersionLess("2.0.0")) {
      ifwCmd += " -c " + this->toplevel + "/config/config.xml";
    }

    ifwCmd += " -p " + this->toplevel + "/packages";

    if (!this->PkgsDirsVector.empty()) {
      for (std::string const& it : this->PkgsDirsVector) {
        ifwCmd += " -p " + it;
      }
    }

    if (!this->RepoDirsVector.empty()) {
      if (!this->IsVersionLess("3.1")) {
        for (std::string const& rd : this->RepoDirsVector) {
          ifwCmd += " --repository " + rd;
        }
      } else {
        cmCPackIFWLogger(WARNING,
                         "The \"CPACK_IFW_REPOSITORIES_DIRECTORIES\" "
                           << "variable is set, but content will be skipped, "
                           << "because this feature available only since "
                           << "QtIFW 3.1. Please update your QtIFW instance."
                           << std::endl);
      }
    }

    if (!this->OnlineOnly && !this->DownloadedPackages.empty()) {
      ifwCmd += " -i ";
      std::set<cmCPackIFWPackage*>::iterator it =
        this->DownloadedPackages.begin();
      ifwCmd += (*it)->Name;
      ++it;
      while (it != this->DownloadedPackages.end()) {
        ifwCmd += "," + (*it)->Name;
        ++it;
      }
    }
    ifwCmd += " " + this->toplevel + "/repository";
    cmCPackIFWLogger(VERBOSE, "Execute: " << ifwCmd << std::endl);
    std::string output;
    int retVal = 1;
    cmCPackIFWLogger(OUTPUT, "- Generate repository" << std::endl);
    bool res = cmSystemTools::RunSingleCommand(
      ifwCmd.c_str(), &output, &output, &retVal, nullptr,
      this->GeneratorVerbose, cmDuration::zero());
    if (!res || retVal) {
      cmGeneratedFileStream ofs(ifwTmpFile);
      ofs << "# Run command: " << ifwCmd << std::endl
          << "# Output:" << std::endl
          << output << std::endl;
      cmCPackIFWLogger(ERROR,
                       "Problem running IFW command: "
                         << ifwCmd << std::endl
                         << "Please check " << ifwTmpFile << " for errors"
                         << std::endl);
      return 0;
    }

    if (!this->Repository.RepositoryUpdate.empty() &&
        !this->Repository.PatchUpdatesXml()) {
      cmCPackIFWLogger(WARNING,
                       "Problem patch IFW \"Updates\" "
                         << "file: "
                         << this->toplevel + "/repository/Updates.xml"
                         << std::endl);
    }

    cmCPackIFWLogger(OUTPUT,
                     "- repository: " << this->toplevel
                                      << "/repository generated" << std::endl);
  }

  // Run binary creator
  {
    std::string ifwCmd = this->BinCreator;
    ifwCmd += " -c " + this->toplevel + "/config/config.xml";

    if (!this->Installer.Resources.empty()) {
      ifwCmd += " -r ";
      std::vector<std::string>::iterator it =
        this->Installer.Resources.begin();
      std::string path = this->toplevel + "/resources/";
      ifwCmd += path + *it;
      ++it;
      while (it != this->Installer.Resources.end()) {
        ifwCmd += "," + path + *it;
        ++it;
      }
    }

    ifwCmd += " -p " + this->toplevel + "/packages";

    if (!this->PkgsDirsVector.empty()) {
      for (std::string const& it : this->PkgsDirsVector) {
        ifwCmd += " -p " + it;
      }
    }

    if (!this->RepoDirsVector.empty()) {
      if (!this->IsVersionLess("3.1")) {
        for (std::string const& rd : this->RepoDirsVector) {
          ifwCmd += " --repository " + rd;
        }
      } else {
        cmCPackIFWLogger(WARNING,
                         "The \"CPACK_IFW_REPOSITORIES_DIRECTORIES\" "
                           << "variable is set, but content will be skipped, "
                           << "because this feature available only since "
                           << "QtIFW 3.1. Please update your QtIFW instance."
                           << std::endl);
      }
    }

    if (this->OnlineOnly) {
      ifwCmd += " --online-only";
    } else if (!this->DownloadedPackages.empty() &&
               !this->Installer.RemoteRepositories.empty()) {
      ifwCmd += " -e ";
      std::set<cmCPackIFWPackage*>::iterator it =
        this->DownloadedPackages.begin();
      ifwCmd += (*it)->Name;
      ++it;
      while (it != this->DownloadedPackages.end()) {
        ifwCmd += "," + (*it)->Name;
        ++it;
      }
    } else if (!this->DependentPackages.empty()) {
      ifwCmd += " -i ";
      // Binary
      std::set<cmCPackIFWPackage*>::iterator bit =
        this->BinaryPackages.begin();
      while (bit != this->BinaryPackages.end()) {
        ifwCmd += (*bit)->Name + ",";
        ++bit;
      }
      // Depend
      DependenceMap::iterator it = this->DependentPackages.begin();
      ifwCmd += it->second.Name;
      ++it;
      while (it != this->DependentPackages.end()) {
        ifwCmd += "," + it->second.Name;
        ++it;
      }
    }
    // TODO: set correct name for multipackages
    if (!this->packageFileNames.empty()) {
      ifwCmd += " " + this->packageFileNames[0];
    } else {
      ifwCmd += " installer";
      ifwCmd += this->OutputExtension;
    }
    cmCPackIFWLogger(VERBOSE, "Execute: " << ifwCmd << std::endl);
    std::string output;
    int retVal = 1;
    cmCPackIFWLogger(OUTPUT, "- Generate package" << std::endl);
    bool res = cmSystemTools::RunSingleCommand(
      ifwCmd.c_str(), &output, &output, &retVal, nullptr,
      this->GeneratorVerbose, cmDuration::zero());
    if (!res || retVal) {
      cmGeneratedFileStream ofs(ifwTmpFile);
      ofs << "# Run command: " << ifwCmd << std::endl
          << "# Output:" << std::endl
          << output << std::endl;
      cmCPackIFWLogger(ERROR,
                       "Problem running IFW command: "
                         << ifwCmd << std::endl
                         << "Please check " << ifwTmpFile << " for errors"
                         << std::endl);
      return 0;
    }
  }

  return 1;
}

const char* cmCPackIFWGenerator::GetPackagingInstallPrefix()
{
  const char* defPrefix = this->cmCPackGenerator::GetPackagingInstallPrefix();

  std::string tmpPref = defPrefix ? defPrefix : "";

  if (this->Components.empty()) {
    tmpPref += "packages/" + this->GetRootPackageName() + "/data";
  }

  this->SetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX", tmpPref.c_str());

  return this->GetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX");
}

const char* cmCPackIFWGenerator::GetOutputExtension()
{
  return this->OutputExtension.c_str();
}

int cmCPackIFWGenerator::InitializeInternal()
{
  // Search Qt Installer Framework tools

  const std::string BinCreatorOpt = "CPACK_IFW_BINARYCREATOR_EXECUTABLE";
  const std::string RepoGenOpt = "CPACK_IFW_REPOGEN_EXECUTABLE";
  const std::string FrameworkVersionOpt = "CPACK_IFW_FRAMEWORK_VERSION";

  if (!this->IsSet(BinCreatorOpt) || !this->IsSet(RepoGenOpt) ||
      !this->IsSet(FrameworkVersionOpt)) {
    this->ReadListFile("CPackIFW.cmake");
  }

  // Look 'binarycreator' executable (needs)

  const char* BinCreatorStr = this->GetOption(BinCreatorOpt);
  if (!BinCreatorStr || cmSystemTools::IsNOTFOUND(BinCreatorStr)) {
    this->BinCreator.clear();
  } else {
    this->BinCreator = BinCreatorStr;
  }

  if (this->BinCreator.empty()) {
    cmCPackIFWLogger(ERROR,
                     "Cannot find QtIFW compiler \"binarycreator\": "
                     "likely it is not installed, or not in your PATH"
                       << std::endl);
    return 0;
  }

  // Look 'repogen' executable (optional)

  const char* RepoGenStr = this->GetOption(RepoGenOpt);
  if (!RepoGenStr || cmSystemTools::IsNOTFOUND(RepoGenStr)) {
    this->RepoGen.clear();
  } else {
    this->RepoGen = RepoGenStr;
  }

  // Framework version
  if (const char* FrameworkVersionSrt = this->GetOption(FrameworkVersionOpt)) {
    this->FrameworkVersion = FrameworkVersionSrt;
  } else {
    this->FrameworkVersion = "1.9.9";
  }

  // Variables that Change Behavior

  // Resolve duplicate names
  this->ResolveDuplicateNames =
    this->IsOn("CPACK_IFW_RESOLVE_DUPLICATE_NAMES");

  // Additional packages dirs
  this->PkgsDirsVector.clear();
  if (const char* dirs = this->GetOption("CPACK_IFW_PACKAGES_DIRECTORIES")) {
    cmSystemTools::ExpandListArgument(dirs, this->PkgsDirsVector);
  }

  // Additional repositories dirs
  this->RepoDirsVector.clear();
  if (const char* dirs =
        this->GetOption("CPACK_IFW_REPOSITORIES_DIRECTORIES")) {
    cmSystemTools::ExpandListArgument(dirs, this->RepoDirsVector);
  }

  // Installer
  this->Installer.Generator = this;
  this->Installer.ConfigureFromOptions();

  // Repository
  this->Repository.Generator = this;
  this->Repository.Name = "Unspecified";
  if (const char* site = this->GetOption("CPACK_DOWNLOAD_SITE")) {
    this->Repository.Url = site;
    this->Installer.RemoteRepositories.push_back(&this->Repository);
  }

  // Repositories
  if (const char* RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) {
    std::vector<std::string> RepoAllVector;
    cmSystemTools::ExpandListArgument(RepoAllStr, RepoAllVector);
    for (std::string const& r : RepoAllVector) {
      this->GetRepository(r);
    }
  }

  if (const char* ifwDownloadAll = this->GetOption("CPACK_IFW_DOWNLOAD_ALL")) {
    this->OnlineOnly = cmSystemTools::IsOn(ifwDownloadAll);
  } else if (const char* cpackDownloadAll =
               this->GetOption("CPACK_DOWNLOAD_ALL")) {
    this->OnlineOnly = cmSystemTools::IsOn(cpackDownloadAll);
  } else {
    this->OnlineOnly = false;
  }

  if (!this->Installer.RemoteRepositories.empty() && this->RepoGen.empty()) {
    cmCPackIFWLogger(ERROR,
                     "Cannot find QtIFW repository generator \"repogen\": "
                     "likely it is not installed, or not in your PATH"
                       << std::endl);
    return 0;
  }

  // Executable suffix
  std::string exeSuffix(this->GetOption("CMAKE_EXECUTABLE_SUFFIX"));
  std::string sysName(this->GetOption("CMAKE_SYSTEM_NAME"));
  if (sysName == "Linux") {
    this->ExecutableSuffix = ".run";
  } else if (sysName == "Windows") {
    this->ExecutableSuffix = ".exe";
  } else if (sysName == "Darwin") {
    this->ExecutableSuffix = ".app";
  } else {
    this->ExecutableSuffix = exeSuffix;
  }

  // Output extension
  if (const char* optOutExt =
        this->GetOption("CPACK_IFW_PACKAGE_FILE_EXTENSION")) {
    this->OutputExtension = optOutExt;
  } else if (sysName == "Darwin") {
    this->OutputExtension = ".dmg";
  } else {
    this->OutputExtension = this->ExecutableSuffix;
  }
  if (this->OutputExtension.empty()) {
    this->OutputExtension = this->cmCPackGenerator::GetOutputExtension();
  }

  return this->Superclass::InitializeInternal();
}

std::string cmCPackIFWGenerator::GetComponentInstallDirNameSuffix(
  const std::string& componentName)
{
  const std::string prefix = "packages/";
  const std::string suffix = "/data";

  if (this->componentPackageMethod == this->ONE_PACKAGE) {
    return std::string(prefix + this->GetRootPackageName() + suffix);
  }

  return prefix +
    this->GetComponentPackageName(&this->Components[componentName]) + suffix;
}

cmCPackComponent* cmCPackIFWGenerator::GetComponent(
  const std::string& projectName, const std::string& componentName)
{
  ComponentsMap::iterator cit = this->Components.find(componentName);
  if (cit != this->Components.end()) {
    return &(cit->second);
  }

  cmCPackComponent* component =
    this->cmCPackGenerator::GetComponent(projectName, componentName);
  if (!component) {
    return component;
  }

  std::string name = this->GetComponentPackageName(component);
  PackagesMap::iterator pit = this->Packages.find(name);
  if (pit != this->Packages.end()) {
    return component;
  }

  cmCPackIFWPackage* package = &this->Packages[name];
  package->Name = name;
  package->Generator = this;
  if (package->ConfigureFromComponent(component)) {
    package->Installer = &this->Installer;
    this->Installer.Packages.insert(
      std::pair<std::string, cmCPackIFWPackage*>(name, package));
    this->ComponentPackages.insert(
      std::pair<cmCPackComponent*, cmCPackIFWPackage*>(component, package));
    if (component->IsDownloaded) {
      this->DownloadedPackages.insert(package);
    } else {
      this->BinaryPackages.insert(package);
    }
  } else {
    this->Packages.erase(name);
    cmCPackIFWLogger(ERROR,
                     "Cannot configure package \""
                       << name << "\" for component \"" << component->Name
                       << "\"" << std::endl);
  }

  return component;
}

cmCPackComponentGroup* cmCPackIFWGenerator::GetComponentGroup(
  const std::string& projectName, const std::string& groupName)
{
  cmCPackComponentGroup* group =
    this->cmCPackGenerator::GetComponentGroup(projectName, groupName);
  if (!group) {
    return group;
  }

  std::string name = this->GetGroupPackageName(group);
  PackagesMap::iterator pit = this->Packages.find(name);
  if (pit != this->Packages.end()) {
    return group;
  }

  cmCPackIFWPackage* package = &this->Packages[name];
  package->Name = name;
  package->Generator = this;
  if (package->ConfigureFromGroup(group)) {
    package->Installer = &this->Installer;
    this->Installer.Packages.insert(
      std::pair<std::string, cmCPackIFWPackage*>(name, package));
    this->GroupPackages.insert(
      std::pair<cmCPackComponentGroup*, cmCPackIFWPackage*>(group, package));
    this->BinaryPackages.insert(package);
  } else {
    this->Packages.erase(name);
    cmCPackIFWLogger(ERROR,
                     "Cannot configure package \""
                       << name << "\" for component group \"" << group->Name
                       << "\"" << std::endl);
  }
  return group;
}

enum cmCPackGenerator::CPackSetDestdirSupport
cmCPackIFWGenerator::SupportsSetDestdir() const
{
  return cmCPackGenerator::SETDESTDIR_SHOULD_NOT_BE_USED;
}

bool cmCPackIFWGenerator::SupportsAbsoluteDestination() const
{
  return false;
}

bool cmCPackIFWGenerator::SupportsComponentInstallation() const
{
  return true;
}

bool cmCPackIFWGenerator::IsOnePackage() const
{
  return this->componentPackageMethod == cmCPackGenerator::ONE_PACKAGE;
}

std::string cmCPackIFWGenerator::GetRootPackageName()
{
  // Default value
  std::string name = "root";
  if (const char* optIFW_PACKAGE_GROUP =
        this->GetOption("CPACK_IFW_PACKAGE_GROUP")) {
    // Configure from root group
    cmCPackIFWPackage package;
    package.Generator = this;
    package.ConfigureFromGroup(optIFW_PACKAGE_GROUP);
    name = package.Name;
  } else if (const char* optIFW_PACKAGE_NAME =
               this->GetOption("CPACK_IFW_PACKAGE_NAME")) {
    // Configure from root package name
    name = optIFW_PACKAGE_NAME;
  } else if (const char* optPACKAGE_NAME =
               this->GetOption("CPACK_PACKAGE_NAME")) {
    // Configure from package name
    name = optPACKAGE_NAME;
  }
  return name;
}

std::string cmCPackIFWGenerator::GetGroupPackageName(
  cmCPackComponentGroup* group) const
{
  std::string name;
  if (!group) {
    return name;
  }
  if (cmCPackIFWPackage* package = this->GetGroupPackage(group)) {
    return package->Name;
  }
  const char* option =
    this->GetOption("CPACK_IFW_COMPONENT_GROUP_" +
                    cmsys::SystemTools::UpperCase(group->Name) + "_NAME");
  name = option ? option : group->Name;
  if (group->ParentGroup) {
    cmCPackIFWPackage* package = this->GetGroupPackage(group->ParentGroup);
    bool dot = !this->ResolveDuplicateNames;
    if (dot && name.substr(0, package->Name.size()) == package->Name) {
      dot = false;
    }
    if (dot) {
      name = package->Name + "." + name;
    }
  }
  return name;
}

std::string cmCPackIFWGenerator::GetComponentPackageName(
  cmCPackComponent* component) const
{
  std::string name;
  if (!component) {
    return name;
  }
  if (cmCPackIFWPackage* package = this->GetComponentPackage(component)) {
    return package->Name;
  }
  std::string prefix = "CPACK_IFW_COMPONENT_" +
    cmsys::SystemTools::UpperCase(component->Name) + "_";
  const char* option = this->GetOption(prefix + "NAME");
  name = option ? option : component->Name;
  if (component->Group) {
    cmCPackIFWPackage* package = this->GetGroupPackage(component->Group);
    if ((this->componentPackageMethod ==
         cmCPackGenerator::ONE_PACKAGE_PER_GROUP) ||
        this->IsOn(prefix + "COMMON")) {
      return package->Name;
    }
    bool dot = !this->ResolveDuplicateNames;
    if (dot && name.substr(0, package->Name.size()) == package->Name) {
      dot = false;
    }
    if (dot) {
      name = package->Name + "." + name;
    }
  }
  return name;
}

cmCPackIFWPackage* cmCPackIFWGenerator::GetGroupPackage(
  cmCPackComponentGroup* group) const
{
  std::map<cmCPackComponentGroup*, cmCPackIFWPackage*>::const_iterator pit =
    this->GroupPackages.find(group);
  return pit != this->GroupPackages.end() ? pit->second : nullptr;
}

cmCPackIFWPackage* cmCPackIFWGenerator::GetComponentPackage(
  cmCPackComponent* component) const
{
  std::map<cmCPackComponent*, cmCPackIFWPackage*>::const_iterator pit =
    this->ComponentPackages.find(component);
  return pit != this->ComponentPackages.end() ? pit->second : nullptr;
}

cmCPackIFWRepository* cmCPackIFWGenerator::GetRepository(
  const std::string& repositoryName)
{
  RepositoriesMap::iterator rit = this->Repositories.find(repositoryName);
  if (rit != this->Repositories.end()) {
    return &(rit->second);
  }

  cmCPackIFWRepository* repository = &this->Repositories[repositoryName];
  repository->Name = repositoryName;
  repository->Generator = this;
  if (repository->ConfigureFromOptions()) {
    if (repository->Update == cmCPackIFWRepository::None) {
      this->Installer.RemoteRepositories.push_back(repository);
    } else {
      this->Repository.RepositoryUpdate.push_back(repository);
    }
  } else {
    this->Repositories.erase(repositoryName);
    repository = nullptr;
    cmCPackIFWLogger(WARNING,
                     "Invalid repository \""
                       << repositoryName << "\""
                       << " configuration. Repository will be skipped."
                       << std::endl);
  }
  return repository;
}
