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

#include <algorithm>
#include <cstring>
#include <map>
#include <ostream>
#include <set>
#include <stdexcept>
#include <utility>

#include "cmsys/Glob.hxx"

#include "cm_sys_stat.h"

#include "cmArchiveWrite.h"
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"

namespace {

class DebGenerator
{
public:
  DebGenerator(cmCPackLog* logger, std::string outputName, std::string workDir,
               std::string topLevelDir, std::string temporaryDir,
               cmValue debianCompressionType, cmValue numThreads,
               cmValue debianArchiveType,
               std::map<std::string, std::string> controlValues,
               bool genShLibs, std::string shLibsFilename, bool genPostInst,
               std::string postInst, bool genPostRm, std::string postRm,
               cmValue controlExtra, bool permissionStrctPolicy,
               std::vector<std::string> packageFiles);

  bool generate() const;

private:
  void generateDebianBinaryFile() const;
  void generateControlFile() const;
  bool generateDataTar() const;
  std::string generateMD5File() const;
  bool generateControlTar(std::string const& md5Filename) const;
  bool generateDeb() const;

  cmCPackLog* Logger;
  const std::string OutputName;
  const std::string WorkDir;
  std::string CompressionSuffix;
  const std::string TopLevelDir;
  const std::string TemporaryDir;
  const std::string DebianArchiveType;
  long NumThreads;
  const std::map<std::string, std::string> ControlValues;
  const bool GenShLibs;
  const std::string ShLibsFilename;
  const bool GenPostInst;
  const std::string PostInst;
  const bool GenPostRm;
  const std::string PostRm;
  cmValue ControlExtra;
  const bool PermissionStrictPolicy;
  const std::vector<std::string> PackageFiles;
  cmArchiveWrite::Compress TarCompressionType;
};

DebGenerator::DebGenerator(
  cmCPackLog* logger, std::string outputName, std::string workDir,
  std::string topLevelDir, std::string temporaryDir,
  cmValue debCompressionType, cmValue numThreads, cmValue debianArchiveType,
  std::map<std::string, std::string> controlValues, bool genShLibs,
  std::string shLibsFilename, bool genPostInst, std::string postInst,
  bool genPostRm, std::string postRm, cmValue controlExtra,
  bool permissionStrictPolicy, std::vector<std::string> packageFiles)
  : Logger(logger)
  , OutputName(std::move(outputName))
  , WorkDir(std::move(workDir))
  , TopLevelDir(std::move(topLevelDir))
  , TemporaryDir(std::move(temporaryDir))
  , DebianArchiveType(debianArchiveType ? *debianArchiveType : "gnutar")
  , ControlValues(std::move(controlValues))
  , GenShLibs(genShLibs)
  , ShLibsFilename(std::move(shLibsFilename))
  , GenPostInst(genPostInst)
  , PostInst(std::move(postInst))
  , GenPostRm(genPostRm)
  , PostRm(std::move(postRm))
  , ControlExtra(controlExtra)
  , PermissionStrictPolicy(permissionStrictPolicy)
  , PackageFiles(std::move(packageFiles))
{
  std::string debianCompressionType = "gzip";
  if (debCompressionType) {
    debianCompressionType = *debCompressionType;
  }

  if (debianCompressionType == "lzma") {
    this->CompressionSuffix = ".lzma";
    this->TarCompressionType = cmArchiveWrite::CompressLZMA;
  } else if (debianCompressionType == "xz") {
    this->CompressionSuffix = ".xz";
    this->TarCompressionType = cmArchiveWrite::CompressXZ;
  } else if (debianCompressionType == "bzip2") {
    this->CompressionSuffix = ".bz2";
    this->TarCompressionType = cmArchiveWrite::CompressBZip2;
  } else if (debianCompressionType == "gzip") {
    this->CompressionSuffix = ".gz";
    this->TarCompressionType = cmArchiveWrite::CompressGZip;
  } else if (debianCompressionType == "zstd") {
    this->CompressionSuffix = ".zst";
    this->TarCompressionType = cmArchiveWrite::CompressZstd;
  } else if (debianCompressionType == "none") {
    this->CompressionSuffix.clear();
    this->TarCompressionType = cmArchiveWrite::CompressNone;
  } else {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error unrecognized compression type: "
                    << debianCompressionType << std::endl);
  }

  if (numThreads != nullptr) {
    if (!cmStrToLong(numThreads, &this->NumThreads)) {
      this->NumThreads = 1;
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Unrecognized number of threads: " << numThreads
                                                       << std::endl);
    }
  } else {
    this->NumThreads = 1;
  }
}

bool DebGenerator::generate() const
{
  this->generateDebianBinaryFile();
  this->generateControlFile();
  if (!this->generateDataTar()) {
    return false;
  }
  std::string md5Filename = this->generateMD5File();
  if (!this->generateControlTar(md5Filename)) {
    return false;
  }
  return this->generateDeb();
}

void DebGenerator::generateDebianBinaryFile() const
{
  // debian-binary file
  const std::string dbfilename = this->WorkDir + "/debian-binary";
  cmGeneratedFileStream out;
  out.Open(dbfilename, false, true);
  out << "2.0\n"; // required for valid debian package
}

void DebGenerator::generateControlFile() const
{
  std::string ctlfilename = this->WorkDir + "/control";

  cmGeneratedFileStream out;
  out.Open(ctlfilename, false, true);
  for (auto const& kv : this->ControlValues) {
    out << kv.first << ": " << kv.second << "\n";
  }

  unsigned long totalSize = 0;
  {
    for (std::string const& file : this->PackageFiles) {
      totalSize += cmSystemTools::FileLength(file);
    }
  }
  out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n\n";
}

bool DebGenerator::generateDataTar() const
{
  std::string filename_data_tar =
    this->WorkDir + "/data.tar" + this->CompressionSuffix;
  cmGeneratedFileStream fileStream_data_tar;
  fileStream_data_tar.Open(filename_data_tar, false, true);
  if (!fileStream_data_tar) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error opening the file \""
                    << filename_data_tar << "\" for writing" << std::endl);
    return false;
  }
  cmArchiveWrite data_tar(fileStream_data_tar, this->TarCompressionType,
                          this->DebianArchiveType, 0,
                          static_cast<int>(this->NumThreads));
  if (!data_tar.Open()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error opening the archive \""
                    << filename_data_tar
                    << "\", ERROR = " << data_tar.GetError() << std::endl);
    return false;
  }

  // uid/gid should be the one of the root user, and this root user has
  // always uid/gid equal to 0.
  data_tar.SetUIDAndGID(0U, 0U);
  data_tar.SetUNAMEAndGNAME("root", "root");

  // now add all directories which have to be compressed
  // collect all top level install dirs for that
  // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would
  // give /usr and /opt
  size_t topLevelLength = this->WorkDir.length();
  cmCPackLogger(cmCPackLog::LOG_DEBUG,
                "WDIR: \"" << this->WorkDir
                           << "\", length = " << topLevelLength << std::endl);
  std::set<std::string> orderedFiles;

  // we have to reconstruct the parent folders as well

  for (std::string currentPath : this->PackageFiles) {
    while (currentPath != this->WorkDir) {
      // the last one IS WorkDir, but we do not want this one:
      // XXX/application/usr/bin/myprogram with GEN_WDIR=XXX/application
      // should not add XXX/application
      orderedFiles.insert(currentPath);
      currentPath = cmSystemTools::CollapseFullPath("..", currentPath);
    }
  }

  for (std::string const& file : orderedFiles) {
    cmCPackLogger(cmCPackLog::LOG_DEBUG,
                  "FILEIT: \"" << file << "\"" << std::endl);
    std::string::size_type slashPos = file.find('/', topLevelLength + 1);
    std::string relativeDir =
      file.substr(topLevelLength, slashPos - topLevelLength);
    cmCPackLogger(cmCPackLog::LOG_DEBUG,
                  "RELATIVEDIR: \"" << relativeDir << "\"" << std::endl);

#ifdef _WIN32
    std::string mode_t_adt_filename = file + ":cmake_mode_t";
    cmsys::ifstream permissionStream(mode_t_adt_filename.c_str());

    mode_t permissions = 0;

    if (permissionStream) {
      permissionStream >> std::oct >> permissions;
    }

    if (permissions != 0) {
      data_tar.SetPermissions(permissions);
    } else if (cmSystemTools::FileIsDirectory(file)) {
      data_tar.SetPermissions(0755);
    } else {
      data_tar.ClearPermissions();
    }
#endif

    // do not recurse because the loop will do it
    if (!data_tar.Add(file, topLevelLength, ".", false)) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Problem adding file to tar:\n"
                    "#top level directory: "
                      << this->WorkDir
                      << "\n"
                         "#file: "
                      << file
                      << "\n"
                         "#error:"
                      << data_tar.GetError() << std::endl);
      return false;
    }
  }
  return true;
}

std::string DebGenerator::generateMD5File() const
{
  std::string md5filename = this->WorkDir + "/md5sums";

  cmGeneratedFileStream out;
  out.Open(md5filename, false, true);

  std::string topLevelWithTrailingSlash = cmStrCat(this->TemporaryDir, '/');
  for (std::string const& file : this->PackageFiles) {
    // hash only regular files
    if (cmSystemTools::FileIsDirectory(file) ||
        cmSystemTools::FileIsSymlink(file)) {
      continue;
    }

    std::string output =
      cmSystemTools::ComputeFileHash(file, cmCryptoHash::AlgoMD5);
    if (output.empty()) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Problem computing the md5 of " << file << std::endl);
    }

    output += "  " + file + "\n";
    // debian md5sums entries are like this:
    // 014f3604694729f3bf19263bac599765  usr/bin/ccmake
    // thus strip the full path (with the trailing slash)
    cmSystemTools::ReplaceString(output, topLevelWithTrailingSlash.c_str(),
                                 "");
    out << output;
  }
  // each line contains a eol.
  // Do not end the md5sum file with yet another (invalid)
  return md5filename;
}

bool DebGenerator::generateControlTar(std::string const& md5Filename) const
{
  std::string filename_control_tar = this->WorkDir + "/control.tar.gz";

  cmGeneratedFileStream fileStream_control_tar;
  fileStream_control_tar.Open(filename_control_tar, false, true);
  if (!fileStream_control_tar) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error opening the file \""
                    << filename_control_tar << "\" for writing" << std::endl);
    return false;
  }
  cmArchiveWrite control_tar(fileStream_control_tar,
                             cmArchiveWrite::CompressGZip,
                             this->DebianArchiveType);
  if (!control_tar.Open()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error opening the archive \""
                    << filename_control_tar
                    << "\", ERROR = " << control_tar.GetError() << std::endl);
    return false;
  }

  // sets permissions and uid/gid for the files
  control_tar.SetUIDAndGID(0u, 0u);
  control_tar.SetUNAMEAndGNAME("root", "root");

  /* permissions are set according to
  https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
  and
  https://lintian.debian.org/tags/control-file-has-bad-permissions.html
  */
  const mode_t permission644 = 0644;
  const mode_t permissionExecute = 0111;
  const mode_t permission755 = permission644 | permissionExecute;

  // for md5sum and control (that we have generated here), we use 644
  // (RW-R--R--)
  // so that deb lintian doesn't warn about it
  control_tar.SetPermissions(permission644);

  // adds control and md5sums
  if (!control_tar.Add(md5Filename, this->WorkDir.length(), ".") ||
      !control_tar.Add(this->WorkDir + "/control", this->WorkDir.length(),
                       ".")) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error adding file to tar:\n"
                  "#top level directory: "
                    << this->WorkDir
                    << "\n"
                       "#file: \"control\" or \"md5sums\"\n"
                       "#error:"
                    << control_tar.GetError() << std::endl);
    return false;
  }

  // adds generated shlibs file
  if (this->GenShLibs) {
    if (!control_tar.Add(this->ShLibsFilename, this->WorkDir.length(), ".")) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error adding file to tar:\n"
                    "#top level directory: "
                      << this->WorkDir
                      << "\n"
                         "#file: \"shlibs\"\n"
                         "#error:"
                      << control_tar.GetError() << std::endl);
      return false;
    }
  }

  // adds LDCONFIG related files
  if (this->GenPostInst) {
    control_tar.SetPermissions(permission755);
    if (!control_tar.Add(this->PostInst, this->WorkDir.length(), ".")) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error adding file to tar:\n"
                    "#top level directory: "
                      << this->WorkDir
                      << "\n"
                         "#file: \"postinst\"\n"
                         "#error:"
                      << control_tar.GetError() << std::endl);
      return false;
    }
    control_tar.SetPermissions(permission644);
  }

  if (this->GenPostRm) {
    control_tar.SetPermissions(permission755);
    if (!control_tar.Add(this->PostRm, this->WorkDir.length(), ".")) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error adding file to tar:\n"
                    "#top level directory: "
                      << this->WorkDir
                      << "\n"
                         "#file: \"postinst\"\n"
                         "#error:"
                      << control_tar.GetError() << std::endl);
      return false;
    }
    control_tar.SetPermissions(permission644);
  }

  // for the other files, we use
  // -either the original permission on the files
  // -either a permission strictly defined by the Debian policies
  if (this->ControlExtra) {
    // permissions are now controlled by the original file permissions

    static const char* strictFiles[] = { "config", "postinst", "postrm",
                                         "preinst", "prerm" };
    std::set<std::string> setStrictFiles(
      strictFiles, strictFiles + sizeof(strictFiles) / sizeof(strictFiles[0]));

    // default
    control_tar.ClearPermissions();

    std::vector<std::string> controlExtraList =
      cmExpandedList(this->ControlExtra);
    for (std::string const& i : controlExtraList) {
      std::string filenamename = cmsys::SystemTools::GetFilenameName(i);
      std::string localcopy = this->WorkDir + "/" + filenamename;

      if (this->PermissionStrictPolicy) {
        control_tar.SetPermissions(
          setStrictFiles.count(filenamename) ? permission755 : permission644);
      }

      // if we can copy the file, it means it does exist, let's add it:
      if (!cmsys::SystemTools::FileExists(i)) {
        cmCPackLogger(cmCPackLog::LOG_WARNING,
                      "Adding file to tar:\n"
                      "#top level directory: "
                        << this->WorkDir
                        << "\n"
                           "#missing file: "
                        << i << std::endl);
      }

      if (cmsys::SystemTools::CopyFileIfDifferent(i, localcopy)) {
        control_tar.Add(localcopy, this->WorkDir.length(), ".");
      }
    }
  }

  return true;
}

bool DebGenerator::generateDeb() const
{
  // ar -r your-package-name.deb debian-binary control.tar.* data.tar.*
  // A debian package .deb is simply an 'ar' archive. The only subtle
  // difference is that debian uses the BSD ar style archive whereas most
  // Linux distro have a GNU ar.
  // See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=161593 for more info
  std::string const outputPath = this->TopLevelDir + "/" + this->OutputName;
  std::string const tlDir = this->WorkDir + "/";
  cmGeneratedFileStream debStream;
  debStream.Open(outputPath, false, true);
  cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd");
  if (!deb.Open()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error opening the archive \""
                    << outputPath << "\", ERROR = " << deb.GetError()
                    << std::endl);
    return false;
  }

  // uid/gid should be the one of the root user, and this root user has
  // always uid/gid equal to 0.
  deb.SetUIDAndGID(0u, 0u);
  deb.SetUNAMEAndGNAME("root", "root");

  if (!deb.Add(tlDir + "debian-binary", tlDir.length()) ||
      !deb.Add(tlDir + "control.tar.gz", tlDir.length()) ||
      !deb.Add(tlDir + "data.tar" + this->CompressionSuffix, tlDir.length())) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error creating debian package:\n"
                  "#top level directory: "
                    << this->TopLevelDir
                    << "\n"
                       "#file: "
                    << this->OutputName
                    << "\n"
                       "#error:"
                    << deb.GetError() << std::endl);
    return false;
  }
  return true;
}

std::vector<std::string> findFilesIn(const std::string& path)
{
  cmsys::Glob gl;
  std::string findExpr = path + "/*";
  gl.RecurseOn();
  gl.SetRecurseListDirs(true);
  gl.SetRecurseThroughSymlinks(false);
  if (!gl.FindFiles(findExpr)) {
    throw std::runtime_error(
      "Cannot find any files in the installed directory");
  }
  std::vector<std::string> files{ gl.GetFiles() };
  // Sort files so that they have a reproducible order
  std::sort(files.begin(), files.end());
  return files;
}

} // end anonymous namespace

cmCPackDebGenerator::cmCPackDebGenerator() = default;

cmCPackDebGenerator::~cmCPackDebGenerator() = default;

int cmCPackDebGenerator::InitializeInternal()
{
  this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
  if (cmIsOff(this->GetOption("CPACK_SET_DESTDIR"))) {
    this->SetOption("CPACK_SET_DESTDIR", "I_ON");
  }
  return this->Superclass::InitializeInternal();
}

int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
                                        std::string const& packageName)
{
  // Begin the archive for this pack
  std::string localToplevel(initialTopLevel);
  std::string packageFileName(
    cmSystemTools::GetParentDirectory(this->toplevel));
  std::string outputFileName(*this->GetOption("CPACK_PACKAGE_FILE_NAME") +
                             "-" + packageName + this->GetOutputExtension());

  localToplevel += "/" + packageName;
  /* replace the TEMP DIRECTORY with the component one */
  this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel);
  packageFileName += "/" + outputFileName;
  /* replace proposed CPACK_OUTPUT_FILE_NAME */
  this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName);
  /* replace the TEMPORARY package file name */
  this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", packageFileName);
  // Tell CPackDeb.cmake the name of the component GROUP.
  this->SetOption("CPACK_DEB_PACKAGE_COMPONENT", packageName);
  // Tell CPackDeb.cmake the path where the component is.
  std::string component_path = cmStrCat('/', packageName);
  this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH", component_path);
  if (!this->ReadListFile("Internal/CPack/CPackDeb.cmake")) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error while execution CPackDeb.cmake" << std::endl);
    return 0;
  }

  return this->createDebPackages();
}

int cmCPackDebGenerator::PackageComponents(bool ignoreGroup)
{
  // Reset package file name list it will be populated during the
  // component packaging run
  this->packageFileNames.clear();
  std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));

  int retval = 1;
  // The default behavior is to have one package by component group
  // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
  if (ignoreGroup) {
    // CPACK_COMPONENTS_IGNORE_GROUPS is set
    // We build 1 package per component
    for (auto const& comp : this->Components) {
      retval &= this->PackageOnePack(initialTopLevel, comp.first);
    }
    return retval;
  }

  for (auto const& compG : this->ComponentGroups) {
    cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                  "Packaging component group: " << compG.first << std::endl);
    // Begin the archive for this group
    retval &= this->PackageOnePack(initialTopLevel, compG.first);
  }
  // Handle Orphan components (components not belonging to any groups)
  for (auto const& 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);
      // Begin the archive for this orphan component
      retval &= this->PackageOnePack(initialTopLevel, comp.first);
    }
  }
  return retval;
}

//----------------------------------------------------------------------
int cmCPackDebGenerator::PackageComponentsAllInOne(
  const std::string& compInstDirName)
{
  /* Reset package file name list it will be populated during the
   * component packaging run*/
  this->packageFileNames.clear();
  std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));

  cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                "Packaging all groups in one package..."
                "(CPACK_COMPONENTS_ALL_[GROUPS_]IN_ONE_PACKAGE is set)"
                  << std::endl);

  // The ALL GROUPS in ONE package case
  std::string localToplevel(initialTopLevel);
  std::string packageFileName(
    cmSystemTools::GetParentDirectory(this->toplevel));
  std::string outputFileName(*this->GetOption("CPACK_PACKAGE_FILE_NAME") +
                             this->GetOutputExtension());
  // all GROUP in one vs all COMPONENT in one
  // if must be here otherwise non component paths have a trailing / while
  // components don't
  if (!compInstDirName.empty()) {
    localToplevel += "/" + compInstDirName;
  }

  /* replace the TEMP DIRECTORY with the component one */
  this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel);
  packageFileName += "/" + outputFileName;
  /* replace proposed CPACK_OUTPUT_FILE_NAME */
  this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName);
  /* replace the TEMPORARY package file name */
  this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", packageFileName);

  if (!compInstDirName.empty()) {
    // Tell CPackDeb.cmake the path where the component is.
    std::string component_path = cmStrCat('/', compInstDirName);
    this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH", component_path);
  }
  if (!this->ReadListFile("Internal/CPack/CPackDeb.cmake")) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error while execution CPackDeb.cmake" << std::endl);
    return 0;
  }

  return this->createDebPackages();
}

int cmCPackDebGenerator::PackageFiles()
{
  /* Are we in the component packaging case */
  if (this->WantsComponentInstallation()) {
    // CASE 1 : COMPONENT ALL-IN-ONE package
    // If ALL GROUPS or ALL COMPONENTS in ONE package has been requested
    // then the package file is unique and should be open here.
    if (this->componentPackageMethod == ONE_PACKAGE) {
      return this->PackageComponentsAllInOne("ALL_COMPONENTS_IN_ONE");
    }
    // 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 this->PackageComponents(this->componentPackageMethod ==
                                   ONE_PACKAGE_PER_COMPONENT);
  }
  // CASE 3 : NON COMPONENT package.
  return this->PackageComponentsAllInOne("");
}

bool cmCPackDebGenerator::createDebPackages()
{
  auto make_package = [this](const std::string& path,
                             const char* const output_var,
                             bool (cmCPackDebGenerator::*creator)()) -> bool {
    try {
      this->packageFiles = findFilesIn(path);
    } catch (const std::runtime_error& ex) {
      cmCPackLogger(cmCPackLog::LOG_ERROR, ex.what() << std::endl);
      return false;
    }

    if ((this->*creator)()) {
      // add the generated package to package file names list
      this->packageFileNames.emplace_back(
        cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
                 this->GetOption(output_var)));
      return true;
    }
    return false;
  };
  bool retval =
    make_package(this->GetOption("GEN_WDIR"), "GEN_CPACK_OUTPUT_FILE_NAME",
                 &cmCPackDebGenerator::createDeb);
  cmValue dbgsymdir_path = this->GetOption("GEN_DBGSYMDIR");
  if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE") && dbgsymdir_path) {
    retval = make_package(dbgsymdir_path, "GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME",
                          &cmCPackDebGenerator::createDbgsymDDeb) &&
      retval;
  }
  return int(retval);
}

bool cmCPackDebGenerator::createDeb()
{
  std::map<std::string, std::string> controlValues;

  // debian policy enforce lower case for package name
  controlValues["Package"] = cmsys::SystemTools::LowerCase(
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_NAME"));
  controlValues["Version"] =
    *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_VERSION");
  controlValues["Section"] =
    *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SECTION");
  controlValues["Priority"] =
    *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PRIORITY");
  controlValues["Architecture"] =
    *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ARCHITECTURE");
  controlValues["Maintainer"] =
    *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER");
  controlValues["Description"] =
    *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION");

  cmValue debian_pkg_source =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE");
  if (cmNonempty(debian_pkg_source)) {
    controlValues["Source"] = *debian_pkg_source;
  }
  cmValue debian_pkg_dep = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DEPENDS");
  if (cmNonempty(debian_pkg_dep)) {
    controlValues["Depends"] = *debian_pkg_dep;
  }
  cmValue debian_pkg_rec =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS");
  if (cmNonempty(debian_pkg_rec)) {
    controlValues["Recommends"] = *debian_pkg_rec;
  }
  cmValue debian_pkg_sug =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS");
  if (cmNonempty(debian_pkg_sug)) {
    controlValues["Suggests"] = *debian_pkg_sug;
  }
  cmValue debian_pkg_url =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_HOMEPAGE");
  if (cmNonempty(debian_pkg_url)) {
    controlValues["Homepage"] = *debian_pkg_url;
  }
  cmValue debian_pkg_predep =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PREDEPENDS");
  if (cmNonempty(debian_pkg_predep)) {
    controlValues["Pre-Depends"] = *debian_pkg_predep;
  }
  cmValue debian_pkg_enhances =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ENHANCES");
  if (cmNonempty(debian_pkg_enhances)) {
    controlValues["Enhances"] = *debian_pkg_enhances;
  }
  cmValue debian_pkg_breaks =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_BREAKS");
  if (cmNonempty(debian_pkg_breaks)) {
    controlValues["Breaks"] = *debian_pkg_breaks;
  }
  cmValue debian_pkg_conflicts =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONFLICTS");
  if (cmNonempty(debian_pkg_conflicts)) {
    controlValues["Conflicts"] = *debian_pkg_conflicts;
  }
  cmValue debian_pkg_provides =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PROVIDES");
  if (cmNonempty(debian_pkg_provides)) {
    controlValues["Provides"] = *debian_pkg_provides;
  }
  cmValue debian_pkg_replaces =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_REPLACES");
  if (cmNonempty(debian_pkg_replaces)) {
    controlValues["Replaces"] = *debian_pkg_replaces;
  }

  const std::string strGenWDIR(this->GetOption("GEN_WDIR"));
  const std::string shlibsfilename = strGenWDIR + "/shlibs";

  cmValue debian_pkg_shlibs =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SHLIBS");
  const bool gen_shibs = this->IsOn("CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS") &&
    cmNonempty(debian_pkg_shlibs);
  if (gen_shibs) {
    cmGeneratedFileStream out;
    out.Open(shlibsfilename, false, true);
    out << debian_pkg_shlibs;
    out << '\n';
  }

  const std::string postinst = strGenWDIR + "/postinst";
  const std::string postrm = strGenWDIR + "/postrm";
  if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTINST")) {
    cmGeneratedFileStream out;
    out.Open(postinst, false, true);
    out << "#!/bin/sh\n\n"
           "set -e\n\n"
           "if [ \"$1\" = \"configure\" ]; then\n"
           "\tldconfig\n"
           "fi\n";
  }
  if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM")) {
    cmGeneratedFileStream out;
    out.Open(postrm, false, true);
    out << "#!/bin/sh\n\n"
           "set -e\n\n"
           "if [ \"$1\" = \"remove\" ]; then\n"
           "\tldconfig\n"
           "fi\n";
  }

  DebGenerator gen(
    this->Logger, this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"), strGenWDIR,
    this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
    this->GetOption("CPACK_TEMPORARY_DIRECTORY"),
    this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE"),
    this->GetOption("CPACK_THREADS"),
    this->GetOption("GEN_CPACK_DEBIAN_ARCHIVE_TYPE"), controlValues, gen_shibs,
    shlibsfilename, this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTINST"), postinst,
    this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM"), postrm,
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA"),
    this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"),
    this->packageFiles);

  return gen.generate();
}

bool cmCPackDebGenerator::createDbgsymDDeb()
{
  // Packages containing debug symbols follow the same structure as .debs
  // but have different metadata and content.

  std::map<std::string, std::string> controlValues;
  // debian policy enforce lower case for package name
  std::string packageNameLower = cmsys::SystemTools::LowerCase(
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_NAME"));
  cmValue debian_pkg_version =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_VERSION");

  controlValues["Package"] = packageNameLower + "-dbgsym";
  controlValues["Package-Type"] = "ddeb";
  controlValues["Version"] = *debian_pkg_version;
  controlValues["Auto-Built-Package"] = "debug-symbols";
  controlValues["Depends"] =
    *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_NAME") + std::string(" (= ") +
    *debian_pkg_version + ")";
  controlValues["Section"] = "debug";
  controlValues["Priority"] = "optional";
  controlValues["Architecture"] =
    *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ARCHITECTURE");
  controlValues["Maintainer"] =
    *this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER");
  controlValues["Description"] =
    std::string("debug symbols for ") + packageNameLower;

  cmValue debian_pkg_source =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE");
  if (cmNonempty(debian_pkg_source)) {
    controlValues["Source"] = *debian_pkg_source;
  }
  cmValue debian_build_ids = this->GetOption("GEN_BUILD_IDS");
  if (cmNonempty(debian_build_ids)) {
    controlValues["Build-Ids"] = *debian_build_ids;
  }

  DebGenerator gen(
    this->Logger, this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"),
    this->GetOption("GEN_DBGSYMDIR"),
    this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
    this->GetOption("CPACK_TEMPORARY_DIRECTORY"),
    this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE"),
    this->GetOption("CPACK_THREADS"),
    this->GetOption("GEN_CPACK_DEBIAN_ARCHIVE_TYPE"), controlValues, false, "",
    false, "", false, "", nullptr,
    this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"),
    this->packageFiles);

  return gen.generate();
}

bool cmCPackDebGenerator::SupportsComponentInstallation() const
{
  return this->IsOn("CPACK_DEB_COMPONENT_INSTALL");
}

std::string cmCPackDebGenerator::GetComponentInstallDirNameSuffix(
  const std::string& componentName)
{
  if (this->componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) {
    return componentName;
  }

  if (this->componentPackageMethod == ONE_PACKAGE) {
    return { "ALL_COMPONENTS_IN_ONE" };
  }
  // We have to find the name of the COMPONENT GROUP
  // the current COMPONENT belongs to.
  std::string groupVar =
    "CPACK_COMPONENT_" + cmSystemTools::UpperCase(componentName) + "_GROUP";
  if (nullptr != this->GetOption(groupVar)) {
    return *this->GetOption(groupVar);
  }
  return componentName;
}
