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

#include "cmsys/SystemTools.hxx"

#include "cmCPackLog.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmake.h"

// Includes needed for implementation of RenameFile.  This is not in
// system tools because it is not implemented robustly enough to move
// files across directories.
#ifdef _WIN32
#  include <windows.h>

#  include "cm_sys_stat.h"
#endif

cmCPackCygwinSourceGenerator::cmCPackCygwinSourceGenerator()
  : cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr", ".tar.bz2")
{
}

cmCPackCygwinSourceGenerator::~cmCPackCygwinSourceGenerator()
{
}

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

int cmCPackCygwinSourceGenerator::PackageFiles()
{
  // Create a tar file of the sources
  std::string packageDirFileName =
    cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), ".tar.bz2");
  packageFileNames[0] = packageDirFileName;
  std::string output;
  // create tar.bz2 file with the list of source files
  if (!this->cmCPackArchiveGenerator::PackageFiles()) {
    return 0;
  }
  // Now create a tar file that contains the above .tar.bz2 file
  // and the CPACK_CYGWIN_PATCH_FILE and CPACK_TOPLEVEL_DIRECTORY
  // files
  std::string compressOutFile = packageDirFileName;
  // at this point compressOutFile is the full path to
  // _CPack_Package/.../package-2.5.0.tar.bz2
  // we want to create a tar _CPack_Package/.../package-2.5.0-1-src.tar.bz2
  // with these
  //   _CPack_Package/.../package-2.5.0-1.patch
  //   _CPack_Package/.../package-2.5.0-1.sh
  //   _CPack_Package/.../package-2.5.0.tar.bz2
  // the -1 is CPACK_CYGWIN_PATCH_NUMBER

  // first copy the patch file and the .sh file
  // to the toplevel cpack temp dir

  // copy the patch file into place
  if (!this->GetOption("CPACK_CYGWIN_PATCH_FILE")) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "No patch file specified for cygwin sources.");
    return 0;
  }
  if (!cmSystemTools::CopyFileAlways(
        this->GetOption("CPACK_CYGWIN_PATCH_FILE"),
        this->GetOption("CPACK_TOPLEVEL_DIRECTORY"))) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "problem copying: ["
                    << this->GetOption("CPACK_CYGWIN_PATCH_FILE") << "]\nto\n["
                    << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "]\n");
    return 0;
  }
  if (!this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT")) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "No build script specified for cygwin sources.");
    return 0;
  }
  // copy the build script into place
  if (!cmSystemTools::CopyFileAlways(
        this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT"),
        this->GetOption("CPACK_TOPLEVEL_DIRECTORY"))) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "problem copying: "
                    << this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT") << "\nto\n"
                    << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "]\n");
    return 0;
  }
  std::string outerTarFile =
    cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), '-');
  const char* patch = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER");
  if (!patch) {
    cmCPackLogger(cmCPackLog::LOG_WARNING,
                  "CPACK_CYGWIN_PATCH_NUMBER"
                    << " not specified, defaulting to 1\n");
    patch = "1";
  }
  outerTarFile += patch;
  outerTarFile += "-src.tar.bz2";
  std::string tmpDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  std::string buildScript =
    cmStrCat(tmpDir, '/',
             cmSystemTools::GetFilenameName(
               this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT")));
  std::string patchFile =
    cmStrCat(tmpDir, '/',
             cmSystemTools::GetFilenameName(
               this->GetOption("CPACK_CYGWIN_PATCH_FILE")));

  std::string file = cmSystemTools::GetFilenameName(compressOutFile);
  std::string sourceTar =
    cmStrCat(cmSystemTools::GetFilenamePath(compressOutFile), '/', file);
  /* reset list of file to be packaged */
  files.clear();
  // a source release in cygwin should have the build script used
  // to build the package, the patch file that is different from the
  // regular upstream version of the sources, and a bziped tar file
  // of the original sources
  files.push_back(buildScript);
  files.push_back(patchFile);
  files.push_back(sourceTar);
  /* update the name of the produced package */
  packageFileNames[0] = outerTarFile;
  /* update the toplevel dir */
  toplevel = tmpDir;
  if (!this->cmCPackArchiveGenerator::PackageFiles()) {
    return 0;
  }
  return 1;
}

const char* cmCPackCygwinSourceGenerator::GetPackagingInstallPrefix()
{
  this->InstallPrefix =
    cmStrCat('/', this->GetOption("CPACK_PACKAGE_FILE_NAME"));
  return this->InstallPrefix.c_str();
}

const char* cmCPackCygwinSourceGenerator::GetOutputExtension()
{
  this->OutputExtension = "-";
  const char* patch = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER");
  if (!patch) {
    cmCPackLogger(cmCPackLog::LOG_WARNING,
                  "CPACK_CYGWIN_PATCH_NUMBER"
                    << " not specified, defaulting to 1\n");
    patch = "1";
  }
  this->OutputExtension += patch;
  this->OutputExtension += "-src.tar.bz2";
  return this->OutputExtension.c_str();
}
