/* 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() = default;

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, &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, &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;
}
