/* 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 "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
#include <assert.h>
#include <map>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <string>

#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.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 = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
    resDir += "/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 = packageDirFileName;
    resDir += "/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 = 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;
    }

    // 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 = this->GetOption("CPACK_PACKAGE_DIRECTORY");
      uploadDirectory += "/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 = toplevel;
      packageDir += '/';
      packageDir += 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 = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  tmpFile += "/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().c_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 = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  tmpFile += "/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 = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
    descriptionFile += '/' + 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 = ".";
    moduleVersionSuffix += component.Name;
    this->SetOption("CPACK_MODULE_VERSION_SUFFIX",
                    moduleVersionSuffix.c_str());
    std::string infoFileName = component.Name;
    infoFileName += "-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 = "com.";
    pkgId += this->GetOption("CPACK_PACKAGE_VENDOR");
    pkgId += '.';
    pkgId += this->GetOption("CPACK_PACKAGE_NAME");
    pkgId += '.';
    pkgId += 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);
}
