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

#include <cstdio>
#include <string>
#include <vector>

#include <fcntl.h>

#include "cmsys/FStream.hxx"

#include "cm_sys_stat.h"

#include "cmArchiveWrite.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmSystemTools.h"
#include "cmValue.h"

cmCPackSTGZGenerator::cmCPackSTGZGenerator()
  : cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr", ".sh")
{
}

cmCPackSTGZGenerator::~cmCPackSTGZGenerator() = default;

int cmCPackSTGZGenerator::InitializeInternal()
{
  this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "0");

  std::string inFile = this->FindTemplate("CPack.STGZ_Header.sh.in");
  if (inFile.empty()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Cannot find template file: " << inFile << std::endl);
    return 0;
  }
  this->SetOptionIfNotSet("CPACK_STGZ_HEADER_FILE", inFile);
  this->SetOptionIfNotSet("CPACK_AT_SIGN", "@");

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

int cmCPackSTGZGenerator::PackageFiles()
{
  bool retval = true;
  if (!this->Superclass::PackageFiles()) {
    return 0;
  }

  /* TGZ generator (our Superclass) may
   * have generated several packages (component packaging)
   * so we must iterate over generated packages.
   */
  for (std::string const& pfn : this->packageFileNames) {
    retval &= static_cast<bool>(
      cmSystemTools::SetPermissions(pfn.c_str(),
#if defined(_MSC_VER) || defined(__MINGW32__)
                                    S_IREAD | S_IWRITE | S_IEXEC
#else
                                    S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
                                      S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH |
                                      S_IXOTH
#endif
                                    ));
  }
  return retval;
}

int cmCPackSTGZGenerator::GenerateHeader(std::ostream* os)
{
  cmCPackLogger(cmCPackLog::LOG_DEBUG, "Writing header" << std::endl);
  int counter = 0;

  std::string inLicFile = this->GetOption("CPACK_RESOURCE_FILE_LICENSE");
  std::string line;
  cmsys::ifstream ilfs(inLicFile.c_str());
  std::string licenseText;
  while (cmSystemTools::GetLineFromStream(ilfs, line)) {
    licenseText += line + "\n";
  }
  this->SetOptionIfNotSet("CPACK_RESOURCE_FILE_LICENSE_CONTENT", licenseText);

  const char headerLengthTag[] = "###CPACK_HEADER_LENGTH###";

  // Create the header
  std::string inFile = this->GetOption("CPACK_STGZ_HEADER_FILE");
  cmsys::ifstream ifs(inFile.c_str());
  std::string packageHeaderText;
  while (cmSystemTools::GetLineFromStream(ifs, line)) {
    packageHeaderText += line + "\n";
  }

  // Configure in the values
  std::string res;
  this->ConfigureString(packageHeaderText, res);

  // Count the lines
  const char* ptr = res.c_str();
  while (*ptr) {
    if (*ptr == '\n') {
      counter++;
    }
    ++ptr;
  }
  counter++;
  cmCPackLogger(cmCPackLog::LOG_DEBUG,
                "Number of lines: " << counter << std::endl);
  char buffer[1024];
  snprintf(buffer, sizeof(buffer), "%d", counter);
  cmSystemTools::ReplaceString(res, headerLengthTag, buffer);

  // Write in file
  *os << res;
  return this->Superclass::GenerateHeader(os);
}
