/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/

#include "cmCPackIFWGenerator.h"

#include <CPack/cmCPackComponentGroup.h>
#include <CPack/cmCPackLog.h>

#include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>
#include <cmsys/RegularExpression.hxx>
#include <cmsys/SystemTools.hxx>

#include <cmGeneratedFileStream.h>
#include <cmGlobalGenerator.h>
#include <cmMakefile.h>
#include <cmSystemTools.h>
#include <cmTimestamp.h>
#include <cmVersionConfig.h>
#include <cmXMLWriter.h>

cmCPackIFWGenerator::cmCPackIFWGenerator()
{
}

cmCPackIFWGenerator::~cmCPackIFWGenerator()
{
}

bool cmCPackIFWGenerator::IsVersionLess(const char* version)
{
  return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
                                       FrameworkVersion.data(), version);
}

bool cmCPackIFWGenerator::IsVersionGreater(const char* version)
{
  return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER,
                                       FrameworkVersion.data(), version);
}

bool cmCPackIFWGenerator::IsVersionEqual(const char* version)
{
  return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
                                       FrameworkVersion.data(), version);
}

int cmCPackIFWGenerator::PackageFiles()
{
  cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Configuration" << std::endl);

  // Installer configuragion
  Installer.GenerateInstallerFile();

  // Packages configuration
  Installer.GeneratePackageFiles();

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

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

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

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

    if (!PkgsDirsVector.empty()) {
      for (std::vector<std::string>::iterator it = PkgsDirsVector.begin();
           it != PkgsDirsVector.end(); ++it) {
        ifwCmd += " -p " + *it;
      }
    }

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

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

    cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- repository: "
                    << this->toplevel << "/repository generated" << std::endl);
  }

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

    if (!PkgsDirsVector.empty()) {
      for (std::vector<std::string>::iterator it = PkgsDirsVector.begin();
           it != PkgsDirsVector.end(); ++it) {
        ifwCmd += " -p " + *it;
      }
    }

    if (OnlineOnly) {
      ifwCmd += " --online-only";
    } else if (!DownloadedPackages.empty() &&
               !Installer.RemoteRepositories.empty()) {
      ifwCmd += " -e ";
      std::set<cmCPackIFWPackage*>::iterator it = DownloadedPackages.begin();
      ifwCmd += (*it)->Name;
      ++it;
      while (it != DownloadedPackages.end()) {
        ifwCmd += "," + (*it)->Name;
        ++it;
      }
    } else if (!DependentPackages.empty()) {
      ifwCmd += " -i ";
      // Binary
      std::set<cmCPackIFWPackage*>::iterator bit = BinaryPackages.begin();
      while (bit != BinaryPackages.end()) {
        ifwCmd += (*bit)->Name + ",";
        ++bit;
      }
      // Depend
      DependenceMap::iterator it = DependentPackages.begin();
      ifwCmd += it->second.Name;
      ++it;
      while (it != DependentPackages.end()) {
        ifwCmd += "," + it->second.Name;
        ++it;
      }
    }
    // TODO: set correct name for multipackages
    if (!this->packageFileNames.empty()) {
      ifwCmd += " " + packageFileNames[0];
    } else {
      ifwCmd += " installer";
    }
    cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ifwCmd << std::endl);
    std::string output;
    int retVal = 1;
    cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Generate package" << std::endl);
    bool res = cmSystemTools::RunSingleCommand(
      ifwCmd.c_str(), &output, &output, &retVal, 0, this->GeneratorVerbose, 0);
    if (!res || retVal) {
      cmGeneratedFileStream ofs(ifwTmpFile.c_str());
      ofs << "# Run command: " << ifwCmd << std::endl
          << "# Output:" << std::endl
          << output << std::endl;
      cmCPackLogger(cmCPackLog::LOG_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 = cmCPackGenerator::GetPackagingInstallPrefix();

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

  if (this->Components.empty()) {
    tmpPref += "packages/" + 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 ExecutableSuffix.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)) {
    BinCreator = "";
  } else {
    BinCreator = BinCreatorStr;
  }

  if (BinCreator.empty()) {
    cmCPackLogger(cmCPackLog::LOG_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)) {
    RepoGen = "";
  } else {
    RepoGen = RepoGenStr;
  }

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

  // Variables that Change Behavior

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

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

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

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

  // Repositories
  if (const char* RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) {
    std::vector<std::string> RepoAllVector;
    cmSystemTools::ExpandListArgument(RepoAllStr, RepoAllVector);
    for (std::vector<std::string>::iterator rit = RepoAllVector.begin();
         rit != RepoAllVector.end(); ++rit) {
      GetRepository(*rit);
    }
  }

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

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

  // Executable suffix
  if (const char* optExeSuffix = this->GetOption("CMAKE_EXECUTABLE_SUFFIX")) {
    ExecutableSuffix = optExeSuffix;
    if (ExecutableSuffix.empty()) {
      std::string sysName(this->GetOption("CMAKE_SYSTEM_NAME"));
      if (sysName == "Linux") {
        ExecutableSuffix = ".run";
      }
    }
  } else {
    ExecutableSuffix = 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 (componentPackageMethod == ONE_PACKAGE) {
    return std::string(prefix + GetRootPackageName() + suffix);
  }

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

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

  cmCPackComponent* component =
    cmCPackGenerator::GetComponent(projectName, componentName);
  if (!component)
    return component;

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

  cmCPackIFWPackage* package = &Packages[name];
  package->Name = name;
  package->Generator = this;
  if (package->ConfigureFromComponent(component)) {
    package->Installer = &Installer;
    Installer.Packages.insert(
      std::pair<std::string, cmCPackIFWPackage*>(name, package));
    ComponentPackages.insert(
      std::pair<cmCPackComponent*, cmCPackIFWPackage*>(component, package));
    if (component->IsDownloaded) {
      DownloadedPackages.insert(package);
    } else {
      BinaryPackages.insert(package);
    }
  } else {
    Packages.erase(name);
    cmCPackLogger(cmCPackLog::LOG_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 =
    cmCPackGenerator::GetComponentGroup(projectName, groupName);
  if (!group)
    return group;

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

  cmCPackIFWPackage* package = &Packages[name];
  package->Name = name;
  package->Generator = this;
  if (package->ConfigureFromGroup(group)) {
    package->Installer = &Installer;
    Installer.Packages.insert(
      std::pair<std::string, cmCPackIFWPackage*>(name, package));
    GroupPackages.insert(
      std::pair<cmCPackComponentGroup*, cmCPackIFWPackage*>(group, package));
    BinaryPackages.insert(package);
  } else {
    Packages.erase(name);
    cmCPackLogger(cmCPackLog::LOG_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 componentPackageMethod == 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 = GetGroupPackage(group)) {
    return package->Name;
  }
  const char* option =
    GetOption("CPACK_IFW_COMPONENT_GROUP_" +
              cmsys::SystemTools::UpperCase(group->Name) + "_NAME");
  name = option ? option : group->Name;
  if (group->ParentGroup) {
    cmCPackIFWPackage* package = GetGroupPackage(group->ParentGroup);
    bool dot = !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 = GetComponentPackage(component)) {
    return package->Name;
  }
  std::string prefix = "CPACK_IFW_COMPONENT_" +
    cmsys::SystemTools::UpperCase(component->Name) + "_";
  const char* option = GetOption(prefix + "NAME");
  name = option ? option : component->Name;
  if (component->Group) {
    cmCPackIFWPackage* package = GetGroupPackage(component->Group);
    if ((componentPackageMethod == ONE_PACKAGE_PER_GROUP) ||
        IsOn(prefix + "COMMON")) {
      return package->Name;
    }
    bool dot = !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 =
    GroupPackages.find(group);
  return pit != GroupPackages.end() ? pit->second : 0;
}

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

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

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

void cmCPackIFWGenerator::WriteGeneratedByToStrim(cmXMLWriter& xout)
{
  std::stringstream comment;
  comment << "Generated by CPack " << CMake_VERSION << " IFW generator "
          << "for QtIFW ";
  if (IsVersionLess("2.0")) {
    comment << "less 2.0";
  } else {
    comment << FrameworkVersion;
  }
  comment << " tools at " << cmTimestamp().CurrentTime("", true);
  xout.Comment(comment.str().c_str());
}
