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

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

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

cmCPackProductBuildGenerator::cmCPackProductBuildGenerator()
{
  this->componentPackageMethod = ONE_PACKAGE;
}

cmCPackProductBuildGenerator::~cmCPackProductBuildGenerator()
{
}

int cmCPackProductBuildGenerator::PackageFiles()
{
  // TODO: Use toplevel
  //       It is used! Is this an obsolete comment?

  std::string packageDirFileName =
    this->GetOption("CPACK_TEMPORARY_DIRECTORY");

  // Create the directory where component packages will be built.
  std::string basePackageDir = packageDirFileName;
  basePackageDir += "/Contents/Packages";
  if (!cmsys::SystemTools::MakeDirectory(basePackageDir.c_str())) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Problem creating component packages directory: "
                    << basePackageDir << std::endl);
    return 0;
  }

  if (!this->Components.empty()) {
    std::map<std::string, cmCPackComponent>::iterator compIt;
    for (compIt = this->Components.begin(); compIt != this->Components.end();
         ++compIt) {
      std::string packageDir = toplevel;
      packageDir += '/';
      packageDir += compIt->first;
      if (!this->GenerateComponentPackage(basePackageDir,
                                          GetPackageName(compIt->second),
                                          packageDir, &compIt->second)) {
        return 0;
      }
    }
  } else {
    if (!this->GenerateComponentPackage(basePackageDir,
                                        this->GetOption("CPACK_PACKAGE_NAME"),
                                        toplevel, NULL)) {
      return 0;
    }
  }

  // Copy or create all of the resource files we need.
  std::string resDir = packageDirFileName + "/Contents";
  if (!this->CopyCreateResourceFile("License", resDir) ||
      !this->CopyCreateResourceFile("ReadMe", resDir) ||
      !this->CopyCreateResourceFile("Welcome", resDir)) {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the resource files"
                    << std::endl);
    return 0;
  }

  // combine package(s) into a distribution
  WriteDistributionFile(packageDirFileName.c_str());
  std::ostringstream pkgCmd;

  std::string version = this->GetOption("CPACK_PACKAGE_VERSION");
  std::string productbuild = this->GetOption("CPACK_COMMAND_PRODUCTBUILD");

  pkgCmd << productbuild << " --distribution \"" << packageDirFileName
         << "/Contents/distribution.dist\""
         << " --package-path \"" << packageDirFileName << "/Contents/Packages"
         << "\""
         << " --resources \"" << resDir << "\""
         << " --version \"" << version << "\""
         << " \"" << packageFileNames[0] << "\"";

  // Run ProductBuild
  return RunProductBuild(pkgCmd.str());
}

int cmCPackProductBuildGenerator::InitializeInternal()
{
  this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/Applications");

  std::vector<std::string> no_paths;
  std::string program =
    cmSystemTools::FindProgram("pkgbuild", no_paths, false);
  if (program.empty()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find pkgbuild executable"
                    << std::endl);
    return 0;
  }
  this->SetOptionIfNotSet("CPACK_COMMAND_PKGBUILD", program.c_str());

  program = cmSystemTools::FindProgram("productbuild", no_paths, false);
  if (program.empty()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find productbuild executable"
                    << std::endl);
    return 0;
  }
  this->SetOptionIfNotSet("CPACK_COMMAND_PRODUCTBUILD", program.c_str());

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

bool cmCPackProductBuildGenerator::RunProductBuild(const std::string& command)
{
  std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  tmpFile += "/ProductBuildOutput.log";

  cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl);
  std::string output, error_output;
  int retVal = 1;
  bool res =
    cmSystemTools::RunSingleCommand(command.c_str(), &output, &error_output,
                                    &retVal, 0, this->GeneratorVerbose, 0);
  cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Done running command" << std::endl);
  if (!res || retVal) {
    cmGeneratedFileStream ofs(tmpFile.c_str());
    ofs << "# Run command: " << command << std::endl
        << "# Output:" << std::endl
        << output << std::endl;
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Problem running command: " << command << std::endl
                                              << "Please check " << tmpFile
                                              << " for errors" << std::endl);
    return false;
  }
  return true;
}

bool cmCPackProductBuildGenerator::GenerateComponentPackage(
  const std::string& packageFileDir, const std::string& packageFileName,
  const std::string& packageDir, const cmCPackComponent* component)
{
  std::string packageFile = packageFileDir;
  packageFile += '/';
  packageFile += packageFileName;

  cmCPackLogger(cmCPackLog::LOG_OUTPUT, "-   Building component package: "
                  << packageFile << std::endl);

  const char* comp_name = component ? component->Name.c_str() : NULL;

  const char* preflight = this->GetComponentScript("PREFLIGHT", comp_name);
  const char* postflight = this->GetComponentScript("POSTFLIGHT", comp_name);

  std::string resDir = packageFileDir;
  if (component) {
    resDir += "/";
    resDir += component->Name;
  }
  std::string scriptDir = resDir + "/scripts";

  if (!cmsys::SystemTools::MakeDirectory(scriptDir.c_str())) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Problem creating installer directory: " << scriptDir
                                                           << std::endl);
    return 0;
  }

  // if preflight, postflight, or postupgrade are set
  // then copy them into the script directory and make
  // them executable
  if (preflight) {
    this->CopyInstallScript(scriptDir, preflight, "preinstall");
  }
  if (postflight) {
    this->CopyInstallScript(scriptDir, postflight, "postinstall");
  }

  // The command that will be used to run ProductBuild
  std::ostringstream pkgCmd;

  std::string pkgId = "com.";
  pkgId += this->GetOption("CPACK_PACKAGE_VENDOR");
  pkgId += '.';
  pkgId += this->GetOption("CPACK_PACKAGE_NAME");
  if (component) {
    pkgId += '.';
    pkgId += component->Name;
  }

  std::string version = this->GetOption("CPACK_PACKAGE_VERSION");
  std::string pkgbuild = this->GetOption("CPACK_COMMAND_PKGBUILD");

  pkgCmd << pkgbuild << " --root \"" << packageDir << "\""
         << " --identifier \"" << pkgId << "\""
         << " --scripts \"" << scriptDir << "\""
         << " --version \"" << version << "\""
         << " --install-location \"/\""
         << " \"" << packageFile << "\"";

  // Run ProductBuild
  return RunProductBuild(pkgCmd.str());
}

const char* cmCPackProductBuildGenerator::GetComponentScript(
  const char* script, const char* component_name)
{
  std::string scriptname = std::string("CPACK_") + script + "_";
  if (component_name) {
    scriptname += cmSystemTools::UpperCase(component_name);
    scriptname += "_";
  }
  scriptname += "SCRIPT";

  return this->GetOption(scriptname);
}
