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

#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <sstream>
#include <string>

#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"

#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"

static inline unsigned int getVersion(unsigned int major, unsigned int minor)
{
  assert(major < 256 && minor < 256);
  return ((major & 0xFF) << 16 | minor);
}

cmCPackPackageMakerGenerator::cmCPackPackageMakerGenerator()
{
  this->PackageMakerVersion = 0.0;
  this->PackageCompatibilityVersion = getVersion(10, 4);
}

cmCPackPackageMakerGenerator::~cmCPackPackageMakerGenerator() = default;

bool cmCPackPackageMakerGenerator::SupportsComponentInstallation() const
{
  return this->PackageCompatibilityVersion >= getVersion(10, 4);
}

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

  std::string resDir; // Where this package's resources will go.
  std::string packageDirFileName =
    this->GetOption("CPACK_TEMPORARY_DIRECTORY");
  if (this->Components.empty()) {
    packageDirFileName += ".pkg";
    resDir =
      cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/Resources");
  } else {
    packageDirFileName += ".mpkg";
    if (!cmsys::SystemTools::MakeDirectory(packageDirFileName.c_str())) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "unable to create package directory " << packageDirFileName
                                                          << std::endl);
      return 0;
    }

    resDir = cmStrCat(packageDirFileName, "/Contents");
    if (!cmsys::SystemTools::MakeDirectory(resDir.c_str())) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "unable to create package subdirectory " << resDir
                                                             << std::endl);
      return 0;
    }

    resDir += "/Resources";
    if (!cmsys::SystemTools::MakeDirectory(resDir.c_str())) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "unable to create package subdirectory " << resDir
                                                             << std::endl);
      return 0;
    }

    resDir += "/en.lproj";
  }

  const char* preflight = this->GetOption("CPACK_PREFLIGHT_SCRIPT");
  const char* postflight = this->GetOption("CPACK_POSTFLIGHT_SCRIPT");
  const char* postupgrade = this->GetOption("CPACK_POSTUPGRADE_SCRIPT");

  if (this->Components.empty()) {
    // Create directory structure
    std::string preflightDirName = resDir + "/PreFlight";
    std::string postflightDirName = resDir + "/PostFlight";
    // if preflight or postflight scripts not there create directories
    // of the same name, I think this makes it work
    if (!preflight) {
      if (!cmsys::SystemTools::MakeDirectory(preflightDirName.c_str())) {
        cmCPackLogger(cmCPackLog::LOG_ERROR,
                      "Problem creating installer directory: "
                        << preflightDirName << std::endl);
        return 0;
      }
    }
    if (!postflight) {
      if (!cmsys::SystemTools::MakeDirectory(postflightDirName.c_str())) {
        cmCPackLogger(cmCPackLog::LOG_ERROR,
                      "Problem creating installer directory: "
                        << postflightDirName << std::endl);
        return 0;
      }
    }
    // if preflight, postflight, or postupgrade are set
    // then copy them into the resource directory and make
    // them executable
    if (preflight) {
      this->CopyInstallScript(resDir, preflight, "preflight");
    }
    if (postflight) {
      this->CopyInstallScript(resDir, postflight, "postflight");
    }
    if (postupgrade) {
      this->CopyInstallScript(resDir, postupgrade, "postupgrade");
    }
  } else if (postflight) {
    // create a postflight component to house the script
    this->PostFlightComponent.Name = "PostFlight";
    this->PostFlightComponent.DisplayName = "PostFlight";
    this->PostFlightComponent.Description = "PostFlight";
    this->PostFlightComponent.IsHidden = true;

    // empty directory for pkg contents
    std::string packageDir = toplevel + "/" + PostFlightComponent.Name;
    if (!cmsys::SystemTools::MakeDirectory(packageDir.c_str())) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Problem creating component packages directory: "
                      << packageDir << std::endl);
      return 0;
    }

    // create package
    std::string packageFileDir = packageDirFileName + "/Contents/Packages/";
    if (!cmsys::SystemTools::MakeDirectory(packageFileDir.c_str())) {
      cmCPackLogger(
        cmCPackLog::LOG_ERROR,
        "Problem creating component PostFlight Packages directory: "
          << packageFileDir << std::endl);
      return 0;
    }
    std::string packageFile =
      packageFileDir + this->GetPackageName(PostFlightComponent);
    if (!this->GenerateComponentPackage(
          packageFile.c_str(), packageDir.c_str(), PostFlightComponent)) {
      return 0;
    }

    // copy postflight script into resource directory of .pkg
    std::string resourceDir = packageFile + "/Contents/Resources";
    this->CopyInstallScript(resourceDir, postflight, "postflight");
  }

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

    // Create the directory where downloaded component packages will
    // be placed.
    const char* userUploadDirectory =
      this->GetOption("CPACK_UPLOAD_DIRECTORY");
    std::string uploadDirectory;
    if (userUploadDirectory && *userUploadDirectory) {
      uploadDirectory = userUploadDirectory;
    } else {
      uploadDirectory =
        cmStrCat(this->GetOption("CPACK_PACKAGE_DIRECTORY"), "/CPackUploads");
    }

    // Create packages for each component
    bool warnedAboutDownloadCompatibility = false;

    std::map<std::string, cmCPackComponent>::iterator compIt;
    for (compIt = this->Components.begin(); compIt != this->Components.end();
         ++compIt) {
      std::string packageFile;
      if (compIt->second.IsDownloaded) {
        if (this->PackageCompatibilityVersion >= getVersion(10, 5) &&
            this->PackageMakerVersion >= 3.0) {
          // Build this package within the upload directory.
          packageFile = uploadDirectory;

          if (!cmSystemTools::FileExists(uploadDirectory.c_str())) {
            if (!cmSystemTools::MakeDirectory(uploadDirectory.c_str())) {
              cmCPackLogger(cmCPackLog::LOG_ERROR,
                            "Unable to create package upload directory "
                              << uploadDirectory << std::endl);
              return 0;
            }
          }
        } else if (!warnedAboutDownloadCompatibility) {
          if (this->PackageCompatibilityVersion < getVersion(10, 5)) {
            cmCPackLogger(
              cmCPackLog::LOG_WARNING,
              "CPack warning: please set CPACK_OSX_PACKAGE_VERSION to 10.5 "
              "or greater enable downloaded packages. CPack will build a "
              "non-downloaded package."
                << std::endl);
          }

          if (this->PackageMakerVersion < 3) {
            cmCPackLogger(cmCPackLog::LOG_WARNING,
                          "CPack warning: unable to build downloaded "
                          "packages with PackageMaker versions prior "
                          "to 3.0. CPack will build a non-downloaded package."
                            << std::endl);
          }

          warnedAboutDownloadCompatibility = true;
        }
      }

      if (packageFile.empty()) {
        // Build this package within the overall distribution
        // metapackage.
        packageFile = basePackageDir;

        // We're not downloading this component, even if the user
        // requested it.
        compIt->second.IsDownloaded = false;
      }

      packageFile += '/';
      packageFile += GetPackageName(compIt->second);

      std::string packageDir = cmStrCat(toplevel, '/', compIt->first);
      if (!this->GenerateComponentPackage(
            packageFile.c_str(), packageDir.c_str(), compIt->second)) {
        return 0;
      }
    }
  }
  this->SetOption("CPACK_MODULE_VERSION_SUFFIX", "");

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

  if (this->Components.empty()) {
    // Use PackageMaker to build the package.
    std::ostringstream pkgCmd;
    pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
           << "\" -build -p \"" << packageDirFileName << "\"";
    if (this->Components.empty()) {
      pkgCmd << " -f \"" << this->GetOption("CPACK_TEMPORARY_DIRECTORY");
    } else {
      pkgCmd << " -mi \"" << this->GetOption("CPACK_TEMPORARY_DIRECTORY")
             << "/packages/";
    }
    pkgCmd << "\" -r \"" << this->GetOption("CPACK_TOPLEVEL_DIRECTORY")
           << "/Resources\" -i \""
           << this->GetOption("CPACK_TOPLEVEL_DIRECTORY")
           << "/Info.plist\" -d \""
           << this->GetOption("CPACK_TOPLEVEL_DIRECTORY")
           << "/Description.plist\"";
    if (this->PackageMakerVersion > 2.0) {
      pkgCmd << " -v";
    }
    if (!RunPackageMaker(pkgCmd.str().c_str(), packageDirFileName.c_str())) {
      return 0;
    }
  } else {
    // We have built the package in place. Generate the
    // distribution.dist file to describe it for the installer.
    WriteDistributionFile(packageDirFileName.c_str());
  }

  std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
                                 "/hdiutilOutput.log");
  std::ostringstream dmgCmd;
  dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
         << "\" create -ov -fs HFS+ -format UDZO -srcfolder \""
         << packageDirFileName << "\" \"" << packageFileNames[0] << "\"";
  std::string output;
  int retVal = 1;
  int numTries = 10;
  bool res = false;
  while (numTries > 0) {
    res = cmSystemTools::RunSingleCommand(
      dmgCmd.str(), &output, &output, &retVal, nullptr, this->GeneratorVerbose,
      cmDuration::zero());
    if (res && !retVal) {
      numTries = -1;
      break;
    }
    cmSystemTools::Delay(500);
    numTries--;
  }
  if (!res || retVal) {
    cmGeneratedFileStream ofs(tmpFile);
    ofs << "# Run command: " << dmgCmd.str() << std::endl
        << "# Output:" << std::endl
        << output << std::endl;
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Problem running hdiutil command: "
                    << dmgCmd.str() << std::endl
                    << "Please check " << tmpFile << " for errors"
                    << std::endl);
    return 0;
  }

  return 1;
}

int cmCPackPackageMakerGenerator::InitializeInternal()
{
  this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");

  // Starting with Xcode 4.3, PackageMaker is a separate app, and you
  // can put it anywhere you want. So... use a variable for its location.
  // People who put it in unexpected places can use the variable to tell
  // us where it is.
  //
  // Use the following locations, in "most recent installation" order,
  // to search for the PackageMaker app. Assume people who copy it into
  // the new Xcode 4.3 app in "/Applications" will copy it into the nested
  // Applications folder inside the Xcode bundle itself. Or directly in
  // the "/Applications" directory.
  //
  // If found, save result in the CPACK_INSTALLER_PROGRAM variable.

  std::vector<std::string> paths;
  paths.emplace_back("/Applications/Xcode.app/Contents/Applications"
                     "/PackageMaker.app/Contents/MacOS");
  paths.emplace_back("/Applications/Utilities"
                     "/PackageMaker.app/Contents/MacOS");
  paths.emplace_back("/Applications"
                     "/PackageMaker.app/Contents/MacOS");
  paths.emplace_back("/Developer/Applications/Utilities"
                     "/PackageMaker.app/Contents/MacOS");
  paths.emplace_back("/Developer/Applications"
                     "/PackageMaker.app/Contents/MacOS");

  std::string pkgPath;
  const char* inst_program = this->GetOption("CPACK_INSTALLER_PROGRAM");
  if (inst_program && *inst_program) {
    pkgPath = inst_program;
  } else {
    pkgPath = cmSystemTools::FindProgram("PackageMaker", paths, false);
    if (pkgPath.empty()) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Cannot find PackageMaker compiler" << std::endl);
      return 0;
    }
    this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", pkgPath.c_str());
  }

  // Get path to the real PackageMaker, not a symlink:
  pkgPath = cmSystemTools::GetRealPath(pkgPath);
  // Up from there to find the version.plist file in the "Contents" dir:
  std::string contents_dir;
  contents_dir = cmSystemTools::GetFilenamePath(pkgPath);
  contents_dir = cmSystemTools::GetFilenamePath(contents_dir);

  std::string versionFile = contents_dir + "/version.plist";

  if (!cmSystemTools::FileExists(versionFile.c_str())) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Cannot find PackageMaker compiler version file: "
                    << versionFile << std::endl);
    return 0;
  }

  cmsys::ifstream ifs(versionFile.c_str());
  if (!ifs) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Cannot open PackageMaker compiler version file"
                    << std::endl);
    return 0;
  }

  // Check the PackageMaker version
  cmsys::RegularExpression rexKey("<key>CFBundleShortVersionString</key>");
  cmsys::RegularExpression rexVersion("<string>([0-9]+.[0-9.]+)</string>");
  std::string line;
  bool foundKey = false;
  while (cmSystemTools::GetLineFromStream(ifs, line)) {
    if (rexKey.find(line)) {
      foundKey = true;
      break;
    }
  }
  if (!foundKey) {
    cmCPackLogger(
      cmCPackLog::LOG_ERROR,
      "Cannot find CFBundleShortVersionString in the PackageMaker compiler "
      "version file"
        << std::endl);
    return 0;
  }
  if (!cmSystemTools::GetLineFromStream(ifs, line) || !rexVersion.find(line)) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Problem reading the PackageMaker compiler version file: "
                    << versionFile << std::endl);
    return 0;
  }
  this->PackageMakerVersion = atof(rexVersion.match(1).c_str());
  if (this->PackageMakerVersion < 1.0) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Require PackageMaker 1.0 or higher" << std::endl);
    return 0;
  }
  cmCPackLogger(cmCPackLog::LOG_DEBUG,
                "PackageMaker version is: " << this->PackageMakerVersion
                                            << std::endl);

  // Determine the package compatibility version. If it wasn't
  // specified by the user, we define it based on which features the
  // user requested.
  const char* packageCompat = this->GetOption("CPACK_OSX_PACKAGE_VERSION");
  if (packageCompat && *packageCompat) {
    unsigned int majorVersion = 10;
    unsigned int minorVersion = 5;
    int res = sscanf(packageCompat, "%u.%u", &majorVersion, &minorVersion);
    if (res == 2) {
      this->PackageCompatibilityVersion =
        getVersion(majorVersion, minorVersion);
    }
  } else if (this->GetOption("CPACK_DOWNLOAD_SITE")) {
    this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.5");
    this->PackageCompatibilityVersion = getVersion(10, 5);
  } else if (this->GetOption("CPACK_COMPONENTS_ALL")) {
    this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.4");
    this->PackageCompatibilityVersion = getVersion(10, 4);
  } else {
    this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.3");
    this->PackageCompatibilityVersion = getVersion(10, 3);
  }

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

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

bool cmCPackPackageMakerGenerator::RunPackageMaker(const char* command,
                                                   const char* packageFile)
{
  std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
                                 "/PackageMakerOutput.log");

  cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl);
  std::string output;
  int retVal = 1;
  bool res = cmSystemTools::RunSingleCommand(
    command, &output, &output, &retVal, nullptr, this->GeneratorVerbose,
    cmDuration::zero());
  cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                "Done running package maker" << std::endl);
  if (!res || retVal) {
    cmGeneratedFileStream ofs(tmpFile);
    ofs << "# Run command: " << command << std::endl
        << "# Output:" << std::endl
        << output << std::endl;
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Problem running PackageMaker command: "
                    << command << std::endl
                    << "Please check " << tmpFile << " for errors"
                    << std::endl);
    return false;
  }
  // sometimes the command finishes but the directory is not yet
  // created, so try 10 times to see if it shows up
  int tries = 10;
  while (tries > 0 && !cmSystemTools::FileExists(packageFile)) {
    cmSystemTools::Delay(500);
    tries--;
  }
  if (!cmSystemTools::FileExists(packageFile)) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Problem running PackageMaker command: "
                    << command << std::endl
                    << "Package not created: " << packageFile << std::endl);
    return false;
  }

  return true;
}

bool cmCPackPackageMakerGenerator::GenerateComponentPackage(
  const char* packageFile, const char* packageDir,
  const cmCPackComponent& component)
{
  cmCPackLogger(cmCPackLog::LOG_OUTPUT,
                "-   Building component package: " << packageFile
                                                   << std::endl);

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

  if (this->PackageCompatibilityVersion < getVersion(10, 5) ||
      this->PackageMakerVersion < 3.0) {
    // Create Description.plist and Info.plist files for normal Mac OS
    // X packages, which work on Mac OS X 10.3 and newer.
    std::string descriptionFile =
      cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
               component.Name, "-Description.plist");
    cmsys::ofstream out(descriptionFile.c_str());
    cmXMLWriter xout(out);
    xout.StartDocument();
    xout.Doctype("plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\""
                 "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"");
    xout.StartElement("plist");
    xout.Attribute("version", "1.4");
    xout.StartElement("dict");
    xout.Element("key", "IFPkgDescriptionTitle");
    xout.Element("string", component.DisplayName);
    xout.Element("key", "IFPkgDescriptionVersion");
    xout.Element("string", this->GetOption("CPACK_PACKAGE_VERSION"));
    xout.Element("key", "IFPkgDescriptionDescription");
    xout.Element("string", component.Description);
    xout.EndElement(); // dict
    xout.EndElement(); // plist
    xout.EndDocument();
    out.close();

    // Create the Info.plist file for this component
    std::string moduleVersionSuffix = cmStrCat('.', component.Name);
    this->SetOption("CPACK_MODULE_VERSION_SUFFIX",
                    moduleVersionSuffix.c_str());
    std::string infoFileName = cmStrCat(component.Name, "-Info.plist");
    if (!this->CopyResourcePlistFile("Info.plist", infoFileName.c_str())) {
      return false;
    }

    pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
           << "\" -build -p \"" << packageFile << "\""
           << " -f \"" << packageDir << "\""
           << " -i \"" << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "/"
           << infoFileName << "\""
           << " -d \"" << descriptionFile << "\"";
  } else {
    // Create a "flat" package on Mac OS X 10.5 and newer. Flat
    // packages are stored in a single file, rather than a directory
    // like normal packages, and can be downloaded by the installer
    // on-the-fly in Mac OS X 10.5 or newer. Thus, we need to create
    // flat packages when the packages will be downloaded on the fly.
    std::string pkgId =
      cmStrCat("com.", this->GetOption("CPACK_PACKAGE_VENDOR"), '.',
               this->GetOption("CPACK_PACKAGE_NAME"), '.', component.Name);

    pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
           << "\" --root \"" << packageDir << "\""
           << " --id " << pkgId << " --target "
           << this->GetOption("CPACK_OSX_PACKAGE_VERSION") << " --out \""
           << packageFile << "\"";
  }

  // Run PackageMaker
  return RunPackageMaker(pkgCmd.str().c_str(), packageFile);
}
