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

#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmGeneratedFileStream.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"

#include <cstring>
#include <map>
#include <ostream>
#include <utility>
#include <vector>

cmCPackArchiveGenerator::cmCPackArchiveGenerator(cmArchiveWrite::Compress t,
                                                 std::string const& format)
{
  this->Compress = t;
  this->ArchiveFormat = format;
}

cmCPackArchiveGenerator::~cmCPackArchiveGenerator() = default;

std::string cmCPackArchiveGenerator::GetArchiveComponentFileName(
  const std::string& component, bool isGroupName)
{
  std::string componentUpper(cmSystemTools::UpperCase(component));
  std::string packageFileName;

  if (this->IsSet("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME")) {
    packageFileName +=
      this->GetOption("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME");
  } else if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) {
    packageFileName += GetComponentPackageFileName(
      this->GetOption("CPACK_ARCHIVE_FILE_NAME"), component, isGroupName);
  } else {
    packageFileName += GetComponentPackageFileName(
      this->GetOption("CPACK_PACKAGE_FILE_NAME"), component, isGroupName);
  }

  packageFileName += this->GetOutputExtension();

  return packageFileName;
}

int cmCPackArchiveGenerator::InitializeInternal()
{
  this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
  return this->Superclass::InitializeInternal();
}

int cmCPackArchiveGenerator::addOneComponentToArchive(
  cmArchiveWrite& archive, cmCPackComponent* component)
{
  cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                "   - packaging component: " << component->Name << std::endl);
  // Add the files of this component to the archive
  std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
  localToplevel += "/" + component->Name;
  // Change to local toplevel
  cmWorkingDirectory workdir(localToplevel);
  if (workdir.Failed()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Failed to change working directory to "
                    << localToplevel << " : "
                    << std::strerror(workdir.GetLastResult()) << std::endl);
    return 0;
  }
  std::string filePrefix;
  if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) {
    filePrefix = this->GetOption("CPACK_PACKAGE_FILE_NAME");
    filePrefix += "/";
  }
  const char* installPrefix =
    this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
  if (installPrefix && installPrefix[0] == '/' && installPrefix[1] != 0) {
    // add to file prefix and remove the leading '/'
    filePrefix += installPrefix + 1;
    filePrefix += "/";
  }
  for (std::string const& file : component->Files) {
    std::string rp = filePrefix + file;
    cmCPackLogger(cmCPackLog::LOG_DEBUG, "Adding file: " << rp << std::endl);
    archive.Add(rp, 0, nullptr, false);
    if (!archive) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "ERROR while packaging files: " << archive.GetError()
                                                    << std::endl);
      return 0;
    }
  }
  return 1;
}

/*
 * The macro will open/create a file 'filename'
 * an declare and open the associated
 * cmArchiveWrite 'archive' object.
 */
#define DECLARE_AND_OPEN_ARCHIVE(filename, archive)                           \
  cmGeneratedFileStream gf;                                                   \
  gf.Open((filename), false, true);                                           \
  if (!GenerateHeader(&gf)) {                                                 \
    cmCPackLogger(cmCPackLog::LOG_ERROR,                                      \
                  "Problem to generate Header for archive <"                  \
                    << (filename) << ">." << std::endl);                      \
    return 0;                                                                 \
  }                                                                           \
  cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat);            \
  do {                                                                        \
    if (!(archive)) {                                                         \
      cmCPackLogger(cmCPackLog::LOG_ERROR,                                    \
                    "Problem to create archive <"                             \
                      << (filename) << ">, ERROR = " << (archive).GetError()  \
                      << std::endl);                                          \
      return 0;                                                               \
    }                                                                         \
  } while (false)

int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
{
  packageFileNames.clear();
  // The default behavior is to have one package by component group
  // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
  if (!ignoreGroup) {
    for (auto const& compG : this->ComponentGroups) {
      cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                    "Packaging component group: " << compG.first << std::endl);
      // Begin the archive for this group
      std::string packageFileName = std::string(toplevel) + "/" +
        this->GetArchiveComponentFileName(compG.first, true);

      // open a block in order to automatically close archive
      // at the end of the block
      {
        DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive);
        // now iterate over the component of this group
        for (cmCPackComponent* comp : (compG.second).Components) {
          // Add the files of this component to the archive
          addOneComponentToArchive(archive, comp);
        }
      }
      // add the generated package to package file names list
      packageFileNames.push_back(std::move(packageFileName));
    }
    // Handle Orphan components (components not belonging to any groups)
    for (auto& comp : this->Components) {
      // Does the component belong to a group?
      if (comp.second.Group == nullptr) {
        cmCPackLogger(
          cmCPackLog::LOG_VERBOSE,
          "Component <"
            << comp.second.Name
            << "> does not belong to any group, package it separately."
            << std::endl);
        std::string localToplevel(
          this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
        std::string packageFileName = std::string(toplevel);

        localToplevel += "/" + comp.first;
        packageFileName +=
          "/" + this->GetArchiveComponentFileName(comp.first, false);

        {
          DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive);
          // Add the files of this component to the archive
          addOneComponentToArchive(archive, &(comp.second));
        }
        // add the generated package to package file names list
        packageFileNames.push_back(std::move(packageFileName));
      }
    }
  }
  // CPACK_COMPONENTS_IGNORE_GROUPS is set
  // We build 1 package per component
  else {
    for (auto& comp : this->Components) {
      std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
      std::string packageFileName = std::string(toplevel);

      localToplevel += "/" + comp.first;
      packageFileName +=
        "/" + this->GetArchiveComponentFileName(comp.first, false);

      {
        DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive);
        // Add the files of this component to the archive
        addOneComponentToArchive(archive, &(comp.second));
      }
      // add the generated package to package file names list
      packageFileNames.push_back(std::move(packageFileName));
    }
  }
  return 1;
}

int cmCPackArchiveGenerator::PackageComponentsAllInOne()
{
  // reset the package file names
  packageFileNames.clear();
  packageFileNames.emplace_back(toplevel);
  packageFileNames[0] += "/";

  if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) {
    packageFileNames[0] += this->GetOption("CPACK_ARCHIVE_FILE_NAME");
  } else {
    packageFileNames[0] += this->GetOption("CPACK_PACKAGE_FILE_NAME");
  }

  packageFileNames[0] += this->GetOutputExtension();

  cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                "Packaging all groups in one package..."
                "(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE is set)"
                  << std::endl);
  DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive);

  // The ALL COMPONENTS in ONE package case
  for (auto& comp : this->Components) {
    // Add the files of this component to the archive
    addOneComponentToArchive(archive, &(comp.second));
  }

  // archive goes out of scope so it will finalized and closed.
  return 1;
}

int cmCPackArchiveGenerator::PackageFiles()
{
  cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl);

  if (WantsComponentInstallation()) {
    // CASE 1 : COMPONENT ALL-IN-ONE package
    // If ALL COMPONENTS in ONE package has been requested
    // then the package file is unique and should be open here.
    if (componentPackageMethod == ONE_PACKAGE) {
      return PackageComponentsAllInOne();
    }
    // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
    // There will be 1 package for each component group
    // however one may require to ignore component group and
    // in this case you'll get 1 package for each component.
    return PackageComponents(componentPackageMethod ==
                             ONE_PACKAGE_PER_COMPONENT);
  }

  // CASE 3 : NON COMPONENT package.
  DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive);
  cmWorkingDirectory workdir(toplevel);
  if (workdir.Failed()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Failed to change working directory to "
                    << toplevel << " : "
                    << std::strerror(workdir.GetLastResult()) << std::endl);
    return 0;
  }
  for (std::string const& file : files) {
    // Get the relative path to the file
    std::string rp = cmSystemTools::RelativePath(toplevel, file);
    archive.Add(rp, 0, nullptr, false);
    if (!archive) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Problem while adding file <"
                      << file << "> to archive <" << packageFileNames[0]
                      << ">, ERROR = " << archive.GetError() << std::endl);
      return 0;
    }
  }
  // The destructor of cmArchiveWrite will close and finish the write
  return 1;
}

int cmCPackArchiveGenerator::GenerateHeader(std::ostream* /*unused*/)
{
  return 1;
}

bool cmCPackArchiveGenerator::SupportsComponentInstallation() const
{
  // The Component installation support should only
  // be activated if explicitly requested by the user
  // (for backward compatibility reason)
  return IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL");
}
