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

#include <algorithm>
#include <cstdlib>
#include <iomanip>
#include <map>

#include <CoreFoundation/CoreFoundation.h>

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

#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

#ifdef HAVE_CoreServices
// For the old LocaleStringToLangAndRegionCodes() function, to convert
// to the old Script Manager RegionCode values needed for the 'LPic' data
// structure used for generating multi-lingual SLAs.
#  include <CoreServices/CoreServices.h>
#endif

static const char* SLAHeader =
  "data 'LPic' (5000) {\n"
  "    $\"0002 0011 0003 0001 0000 0000 0002 0000\"\n"
  "    $\"0008 0003 0000 0001 0004 0000 0004 0005\"\n"
  "    $\"0000 000E 0006 0001 0005 0007 0000 0007\"\n"
  "    $\"0008 0000 0047 0009 0000 0034 000A 0001\"\n"
  "    $\"0035 000B 0001 0020 000C 0000 0011 000D\"\n"
  "    $\"0000 005B 0004 0000 0033 000F 0001 000C\"\n"
  "    $\"0010 0000 000B 000E 0000\"\n"
  "};\n"
  "\n";

static const char* SLASTREnglish =
  "resource 'STR#' (5002, \"English\") {\n"
  "    {\n"
  "        \"English\",\n"
  "        \"Agree\",\n"
  "        \"Disagree\",\n"
  "        \"Print\",\n"
  "        \"Save...\",\n"
  "        \"You agree to the License Agreement terms when you click \"\n"
  "        \"the \\\"Agree\\\" button.\",\n"
  "        \"Software License Agreement\",\n"
  "        \"This text cannot be saved.  This disk may be full or locked, "
  "or the \"\n"
  "        \"file may be locked.\",\n"
  "        \"Unable to print.  Make sure you have selected a printer.\"\n"
  "    }\n"
  "};\n"
  "\n";

cmCPackDragNDropGenerator::cmCPackDragNDropGenerator()
  : singleLicense(false)
{
  // default to one package file for components
  this->componentPackageMethod = ONE_PACKAGE;
}

cmCPackDragNDropGenerator::~cmCPackDragNDropGenerator() = default;

int cmCPackDragNDropGenerator::InitializeInternal()
{
  // Starting with Xcode 4.3, look in "/Applications/Xcode.app" first:
  //
  std::vector<std::string> paths;
  paths.emplace_back("/Applications/Xcode.app/Contents/Developer/Tools");
  paths.emplace_back("/Developer/Tools");

  const std::string hdiutil_path =
    cmSystemTools::FindProgram("hdiutil", std::vector<std::string>(), false);
  if (hdiutil_path.empty()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Cannot locate hdiutil command" << std::endl);
    return 0;
  }
  this->SetOptionIfNotSet("CPACK_COMMAND_HDIUTIL", hdiutil_path.c_str());

  const std::string setfile_path =
    cmSystemTools::FindProgram("SetFile", paths, false);
  if (setfile_path.empty()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Cannot locate SetFile command" << std::endl);
    return 0;
  }
  this->SetOptionIfNotSet("CPACK_COMMAND_SETFILE", setfile_path.c_str());

  const std::string rez_path = cmSystemTools::FindProgram("Rez", paths, false);
  if (rez_path.empty()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Cannot locate Rez command" << std::endl);
    return 0;
  }
  this->SetOptionIfNotSet("CPACK_COMMAND_REZ", rez_path.c_str());

  if (this->IsSet("CPACK_DMG_SLA_DIR")) {
    slaDirectory = this->GetOption("CPACK_DMG_SLA_DIR");
    if (!slaDirectory.empty() && this->IsSet("CPACK_RESOURCE_FILE_LICENSE")) {
      std::string license_file =
        this->GetOption("CPACK_RESOURCE_FILE_LICENSE");
      if (!license_file.empty() &&
          (license_file.find("CPack.GenericLicense.txt") ==
           std::string::npos)) {
        cmCPackLogger(
          cmCPackLog::LOG_OUTPUT,
          "Both CPACK_DMG_SLA_DIR and CPACK_RESOURCE_FILE_LICENSE specified, "
          "using CPACK_RESOURCE_FILE_LICENSE as a license for all languages."
            << std::endl);
        singleLicense = true;
      }
    }
    if (!this->IsSet("CPACK_DMG_SLA_LANGUAGES")) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "CPACK_DMG_SLA_DIR set but no languages defined "
                    "(set CPACK_DMG_SLA_LANGUAGES)"
                      << std::endl);
      return 0;
    }
    if (!cmSystemTools::FileExists(slaDirectory, false)) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "CPACK_DMG_SLA_DIR does not exist" << std::endl);
      return 0;
    }

    std::vector<std::string> languages =
      cmExpandedList(this->GetOption("CPACK_DMG_SLA_LANGUAGES"));
    if (languages.empty()) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "CPACK_DMG_SLA_LANGUAGES set but empty" << std::endl);
      return 0;
    }
    for (auto const& language : languages) {
      std::string license = slaDirectory + "/" + language + ".license.txt";
      if (!singleLicense && !cmSystemTools::FileExists(license)) {
        cmCPackLogger(cmCPackLog::LOG_ERROR,
                      "Missing license file " << language << ".license.txt"
                                              << std::endl);
        return 0;
      }
      std::string menu = slaDirectory + "/" + language + ".menu.txt";
      if (!cmSystemTools::FileExists(menu)) {
        cmCPackLogger(cmCPackLog::LOG_ERROR,
                      "Missing menu file " << language << ".menu.txt"
                                           << std::endl);
        return 0;
      }
    }
  }

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

const char* cmCPackDragNDropGenerator::GetOutputExtension()
{
  return ".dmg";
}

int cmCPackDragNDropGenerator::PackageFiles()
{
  // gather which directories to make dmg files for
  // multiple directories occur if packaging components or groups separately

  // monolith
  if (this->Components.empty()) {
    return this->CreateDMG(toplevel, packageFileNames[0]);
  }

  // component install
  std::vector<std::string> package_files;

  std::map<std::string, cmCPackComponent>::iterator compIt;
  for (compIt = this->Components.begin(); compIt != this->Components.end();
       ++compIt) {
    std::string name = GetComponentInstallDirNameSuffix(compIt->first);
    package_files.push_back(name);
  }
  std::sort(package_files.begin(), package_files.end());
  package_files.erase(std::unique(package_files.begin(), package_files.end()),
                      package_files.end());

  // loop to create dmg files
  packageFileNames.clear();
  for (auto const& package_file : package_files) {
    std::string full_package_name = std::string(toplevel) + std::string("/");
    if (package_file == "ALL_IN_ONE") {
      full_package_name += this->GetOption("CPACK_PACKAGE_FILE_NAME");
    } else {
      full_package_name += package_file;
    }
    full_package_name += std::string(GetOutputExtension());
    packageFileNames.push_back(full_package_name);

    std::string src_dir = cmStrCat(toplevel, '/', package_file);

    if (0 == this->CreateDMG(src_dir, full_package_name)) {
      return 0;
    }
  }
  return 1;
}

bool cmCPackDragNDropGenerator::CopyFile(std::ostringstream& source,
                                         std::ostringstream& target)
{
  if (!cmSystemTools::CopyFileIfDifferent(source.str(), target.str())) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error copying " << source.str() << " to " << target.str()
                                   << std::endl);

    return false;
  }

  return true;
}

bool cmCPackDragNDropGenerator::CreateEmptyFile(std::ostringstream& target,
                                                size_t size)
{
  cmsys::ofstream fout(target.str().c_str(), std::ios::out | std::ios::binary);
  if (!fout) {
    return false;
  }

  // Seek to desired size - 1 byte
  fout.seekp(size - 1, std::ios::beg);
  char byte = 0;
  // Write one byte to ensure file grows
  fout.write(&byte, 1);

  return true;
}

bool cmCPackDragNDropGenerator::RunCommand(std::ostringstream& command,
                                           std::string* output)
{
  int exit_code = 1;

  bool result = cmSystemTools::RunSingleCommand(
    command.str(), output, output, &exit_code, nullptr, this->GeneratorVerbose,
    cmDuration::zero());

  if (!result || exit_code) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error executing: " << command.str() << std::endl);

    return false;
  }

  return true;
}

int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
                                         const std::string& output_file)
{
  // Get optional arguments ...
  const std::string cpack_package_icon = this->GetOption("CPACK_PACKAGE_ICON")
    ? this->GetOption("CPACK_PACKAGE_ICON")
    : "";

  const std::string cpack_dmg_volume_name =
    this->GetOption("CPACK_DMG_VOLUME_NAME")
    ? this->GetOption("CPACK_DMG_VOLUME_NAME")
    : this->GetOption("CPACK_PACKAGE_FILE_NAME");

  const std::string cpack_dmg_format = this->GetOption("CPACK_DMG_FORMAT")
    ? this->GetOption("CPACK_DMG_FORMAT")
    : "UDZO";

  // Get optional arguments ...
  std::string cpack_license_file =
    this->GetOption("CPACK_RESOURCE_FILE_LICENSE")
    ? this->GetOption("CPACK_RESOURCE_FILE_LICENSE")
    : "";

  const std::string cpack_dmg_background_image =
    this->GetOption("CPACK_DMG_BACKGROUND_IMAGE")
    ? this->GetOption("CPACK_DMG_BACKGROUND_IMAGE")
    : "";

  const std::string cpack_dmg_ds_store = this->GetOption("CPACK_DMG_DS_STORE")
    ? this->GetOption("CPACK_DMG_DS_STORE")
    : "";

  const std::string cpack_dmg_languages =
    this->GetOption("CPACK_DMG_SLA_LANGUAGES")
    ? this->GetOption("CPACK_DMG_SLA_LANGUAGES")
    : "";

  const std::string cpack_dmg_ds_store_setup_script =
    this->GetOption("CPACK_DMG_DS_STORE_SETUP_SCRIPT")
    ? this->GetOption("CPACK_DMG_DS_STORE_SETUP_SCRIPT")
    : "";

  const bool cpack_dmg_disable_applications_symlink =
    this->IsOn("CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK");

  // only put license on dmg if is user provided
  if (!cpack_license_file.empty() &&
      cpack_license_file.find("CPack.GenericLicense.txt") !=
        std::string::npos) {
    cpack_license_file = "";
  }

  // use sla_dir if both sla_dir and license_file are set
  if (!cpack_license_file.empty() && !slaDirectory.empty() && !singleLicense) {
    cpack_license_file = "";
  }

  // The staging directory contains everything that will end-up inside the
  // final disk image ...
  std::ostringstream staging;
  staging << src_dir;

  // Add a symlink to /Applications so users can drag-and-drop the bundle
  // into it unless this behaviour was disabled
  if (!cpack_dmg_disable_applications_symlink) {
    std::ostringstream application_link;
    application_link << staging.str() << "/Applications";
    cmSystemTools::CreateSymlink("/Applications", application_link.str());
  }

  // Optionally add a custom volume icon ...
  if (!cpack_package_icon.empty()) {
    std::ostringstream package_icon_source;
    package_icon_source << cpack_package_icon;

    std::ostringstream package_icon_destination;
    package_icon_destination << staging.str() << "/.VolumeIcon.icns";

    if (!this->CopyFile(package_icon_source, package_icon_destination)) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error copying disk volume icon.  "
                    "Check the value of CPACK_PACKAGE_ICON."
                      << std::endl);

      return 0;
    }
  }

  // Optionally add a custom .DS_Store file
  // (e.g. for setting background/layout) ...
  if (!cpack_dmg_ds_store.empty()) {
    std::ostringstream package_settings_source;
    package_settings_source << cpack_dmg_ds_store;

    std::ostringstream package_settings_destination;
    package_settings_destination << staging.str() << "/.DS_Store";

    if (!this->CopyFile(package_settings_source,
                        package_settings_destination)) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error copying disk volume settings file.  "
                    "Check the value of CPACK_DMG_DS_STORE."
                      << std::endl);

      return 0;
    }
  }

  // Optionally add a custom background image ...
  // Make sure the background file type is the same as the custom image
  // and that the file is hidden so it doesn't show up.
  if (!cpack_dmg_background_image.empty()) {
    const std::string extension =
      cmSystemTools::GetFilenameLastExtension(cpack_dmg_background_image);
    std::ostringstream package_background_source;
    package_background_source << cpack_dmg_background_image;

    std::ostringstream package_background_destination;
    package_background_destination << staging.str()
                                   << "/.background/background" << extension;

    if (!this->CopyFile(package_background_source,
                        package_background_destination)) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error copying disk volume background image.  "
                    "Check the value of CPACK_DMG_BACKGROUND_IMAGE."
                      << std::endl);

      return 0;
    }
  }

  bool remount_image =
    !cpack_package_icon.empty() || !cpack_dmg_ds_store_setup_script.empty();

  std::string temp_image_format = "UDZO";

  // Create 1 MB dummy padding file in staging area when we need to remount
  // image, so we have enough space for storing changes ...
  if (remount_image) {
    std::ostringstream dummy_padding;
    dummy_padding << staging.str() << "/.dummy-padding-file";
    if (!this->CreateEmptyFile(dummy_padding, 1048576)) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error creating dummy padding file." << std::endl);

      return 0;
    }
    temp_image_format = "UDRW";
  }

  // Create a temporary read-write disk image ...
  std::string temp_image =
    cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/temp.dmg");

  std::string create_error;
  std::ostringstream temp_image_command;
  temp_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
  temp_image_command << " create";
  temp_image_command << " -ov";
  temp_image_command << " -srcfolder \"" << staging.str() << "\"";
  temp_image_command << " -volname \"" << cpack_dmg_volume_name << "\"";
  temp_image_command << " -fs HFS+";
  temp_image_command << " -format " << temp_image_format;
  temp_image_command << " \"" << temp_image << "\"";

  if (!this->RunCommand(temp_image_command, &create_error)) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error generating temporary disk image." << std::endl
                                                           << create_error
                                                           << std::endl);

    return 0;
  }

  if (remount_image) {
    // Store that we have a failure so that we always unmount the image
    // before we exit.
    bool had_error = false;

    std::ostringstream attach_command;
    attach_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
    attach_command << " attach";
    attach_command << " \"" << temp_image << "\"";

    std::string attach_output;
    if (!this->RunCommand(attach_command, &attach_output)) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error attaching temporary disk image." << std::endl);

      return 0;
    }

    cmsys::RegularExpression mountpoint_regex(".*(/Volumes/[^\n]+)\n.*");
    mountpoint_regex.find(attach_output.c_str());
    std::string const temp_mount = mountpoint_regex.match(1);
    std::string const temp_mount_name =
      temp_mount.substr(sizeof("/Volumes/") - 1);

    // Remove dummy padding file so we have enough space on RW image ...
    std::ostringstream dummy_padding;
    dummy_padding << temp_mount << "/.dummy-padding-file";
    if (!cmSystemTools::RemoveFile(dummy_padding.str())) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error removing dummy padding file." << std::endl);

      had_error = true;
    }

    // Optionally set the custom icon flag for the image ...
    if (!had_error && !cpack_package_icon.empty()) {
      std::string error;
      std::ostringstream setfile_command;
      setfile_command << this->GetOption("CPACK_COMMAND_SETFILE");
      setfile_command << " -a C";
      setfile_command << " \"" << temp_mount << "\"";

      if (!this->RunCommand(setfile_command, &error)) {
        cmCPackLogger(cmCPackLog::LOG_ERROR,
                      "Error assigning custom icon to temporary disk image."
                        << std::endl
                        << error << std::endl);

        had_error = true;
      }
    }

    // Optionally we can execute a custom apple script to generate
    // the .DS_Store for the volume folder ...
    if (!had_error && !cpack_dmg_ds_store_setup_script.empty()) {
      std::ostringstream setup_script_command;
      setup_script_command << "osascript"
                           << " \"" << cpack_dmg_ds_store_setup_script << "\""
                           << " \"" << temp_mount_name << "\"";
      std::string error;
      if (!this->RunCommand(setup_script_command, &error)) {
        cmCPackLogger(cmCPackLog::LOG_ERROR,
                      "Error executing custom script on disk image."
                        << std::endl
                        << error << std::endl);

        had_error = true;
      }
    }

    std::ostringstream detach_command;
    detach_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
    detach_command << " detach";
    detach_command << " \"" << temp_mount << "\"";

    if (!this->RunCommand(detach_command)) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error detaching temporary disk image." << std::endl);

      return 0;
    }

    if (had_error) {
      return 0;
    }
  }

  if (!cpack_license_file.empty() || !slaDirectory.empty()) {
    // Use old hardcoded style if sla_dir is not set
    bool oldStyle = slaDirectory.empty();
    std::string sla_r =
      cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/sla.r");

    std::vector<std::string> languages;
    if (!oldStyle) {
      cmExpandList(cpack_dmg_languages, languages);
    }

    cmGeneratedFileStream ofs(sla_r);
    ofs << "#include <CoreServices/CoreServices.r>\n\n";
    if (oldStyle) {
      ofs << SLAHeader;
      ofs << "\n";
    } else {
      /*
       * LPic Layout
       * (https://github.com/pypt/dmg-add-license/blob/master/main.c)
       * as far as I can tell (no official documentation seems to exist):
       * struct LPic {
       *  uint16_t default_language; // points to a resid, defaulting to 0,
       *                             // which is the first set language
       *  uint16_t length;
       *  struct {
       *    uint16_t language_code;
       *    uint16_t resid;
       *    uint16_t encoding; // Encoding from TextCommon.h,
       *                       // forcing MacRoman (0) for now. Might need to
       *                       // allow overwrite per license by user later
       *  } item[1];
       * }
       */

      // Create vector first for readability, then iterate to write to ofs
      std::vector<uint16_t> header_data;
      header_data.push_back(0);
      header_data.push_back(languages.size());
      for (size_t i = 0; i < languages.size(); ++i) {
        CFStringRef language_cfstring = CFStringCreateWithCString(
          nullptr, languages[i].c_str(), kCFStringEncodingUTF8);
        CFStringRef iso_language =
          CFLocaleCreateCanonicalLanguageIdentifierFromString(
            nullptr, language_cfstring);
        if (!iso_language) {
          cmCPackLogger(cmCPackLog::LOG_ERROR,
                        languages[i] << " is not a recognized language"
                                     << std::endl);
        }
        char iso_language_cstr[65];
        CFStringGetCString(iso_language, iso_language_cstr,
                           sizeof(iso_language_cstr) - 1,
                           kCFStringEncodingMacRoman);
        LangCode lang = 0;
        RegionCode region = 0;
#ifdef HAVE_CoreServices
        OSStatus err =
          LocaleStringToLangAndRegionCodes(iso_language_cstr, &lang, &region);
        if (err != noErr)
#endif
        {
          cmCPackLogger(cmCPackLog::LOG_ERROR,
                        "No language/region code available for "
                          << iso_language_cstr << std::endl);
          return 0;
        }
#ifdef HAVE_CoreServices
        header_data.push_back(region);
        header_data.push_back(i);
        header_data.push_back(0);
#endif
      }
      ofs << "data 'LPic' (5000) {\n";
      ofs << std::hex << std::uppercase << std::setfill('0');

      for (size_t i = 0; i < header_data.size(); ++i) {
        if (i % 8 == 0) {
          ofs << "    $\"";
        }

        ofs << std::setw(4) << header_data[i];

        if (i % 8 == 7 || i == header_data.size() - 1) {
          ofs << "\"\n";
        } else {
          ofs << " ";
        }
      }
      ofs << "};\n\n";
      // Reset ofs options
      ofs << std::dec << std::nouppercase << std::setfill(' ');
    }

    bool have_write_license_error = false;
    std::string error;

    if (oldStyle) {
      if (!this->WriteLicense(ofs, 0, "", cpack_license_file, &error)) {
        have_write_license_error = true;
      }
    } else {
      for (size_t i = 0; i < languages.size() && !have_write_license_error;
           ++i) {
        if (singleLicense) {
          if (!this->WriteLicense(ofs, i + 5000, languages[i],
                                  cpack_license_file, &error)) {
            have_write_license_error = true;
          }
        } else {
          if (!this->WriteLicense(ofs, i + 5000, languages[i], "", &error)) {
            have_write_license_error = true;
          }
        }
      }
    }

    ofs.Close();

    if (have_write_license_error) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error writing license file to SLA." << std::endl
                                                         << error
                                                         << std::endl);
      return 0;
    }

    if (temp_image_format != "UDZO") {
      temp_image_format = "UDZO";
      // convert to UDZO to enable unflatten/flatten
      std::string temp_udzo = cmStrCat(
        this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/temp-udzo.dmg");

      std::ostringstream udco_image_command;
      udco_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
      udco_image_command << " convert \"" << temp_image << "\"";
      udco_image_command << " -format UDZO";
      udco_image_command << " -ov -o \"" << temp_udzo << "\"";

      if (!this->RunCommand(udco_image_command, &error)) {
        cmCPackLogger(cmCPackLog::LOG_ERROR,
                      "Error converting to UDCO dmg for adding SLA."
                        << std::endl
                        << error << std::endl);
        return 0;
      }
      temp_image = temp_udzo;
    }

    // unflatten dmg
    std::ostringstream unflatten_command;
    unflatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
    unflatten_command << " unflatten ";
    unflatten_command << "\"" << temp_image << "\"";

    if (!this->RunCommand(unflatten_command, &error)) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error unflattening dmg for adding SLA." << std::endl
                                                             << error
                                                             << std::endl);
      return 0;
    }

    // Rez the SLA
    std::ostringstream embed_sla_command;
    embed_sla_command << this->GetOption("CPACK_COMMAND_REZ");
    const char* sysroot = this->GetOption("CPACK_OSX_SYSROOT");
    if (sysroot && sysroot[0] != '\0') {
      embed_sla_command << " -isysroot \"" << sysroot << "\"";
    }
    embed_sla_command << " \"" << sla_r << "\"";
    embed_sla_command << " -a -o ";
    embed_sla_command << "\"" << temp_image << "\"";

    if (!this->RunCommand(embed_sla_command, &error)) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error adding SLA." << std::endl
                                        << error << std::endl);
      return 0;
    }

    // flatten dmg
    std::ostringstream flatten_command;
    flatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
    flatten_command << " flatten ";
    flatten_command << "\"" << temp_image << "\"";

    if (!this->RunCommand(flatten_command, &error)) {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Error flattening dmg for adding SLA." << std::endl
                                                           << error
                                                           << std::endl);
      return 0;
    }
  }

  // Create the final compressed read-only disk image ...
  std::ostringstream final_image_command;
  final_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
  final_image_command << " convert \"" << temp_image << "\"";
  final_image_command << " -format ";
  final_image_command << cpack_dmg_format;
  final_image_command << " -imagekey";
  final_image_command << " zlib-level=9";
  final_image_command << " -o \"" << output_file << "\"";

  std::string convert_error;

  if (!this->RunCommand(final_image_command, &convert_error)) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error compressing disk image." << std::endl
                                                  << convert_error
                                                  << std::endl);

    return 0;
  }

  return 1;
}

bool cmCPackDragNDropGenerator::SupportsComponentInstallation() const
{
  return true;
}

std::string cmCPackDragNDropGenerator::GetComponentInstallDirNameSuffix(
  const std::string& componentName)
{
  // we want to group components together that go in the same dmg package
  std::string package_file_name = this->GetOption("CPACK_PACKAGE_FILE_NAME");

  // we have 3 mutually exclusive modes to work in
  // 1. all components in one package
  // 2. each group goes in its own package with left over
  //    components in their own package
  // 3. ignore groups - if grouping is defined, it is ignored
  //    and each component goes in its own package

  if (this->componentPackageMethod == ONE_PACKAGE) {
    return "ALL_IN_ONE";
  }

  if (this->componentPackageMethod == ONE_PACKAGE_PER_GROUP) {
    // We have to find the name of the COMPONENT GROUP
    // the current COMPONENT belongs to.
    std::string groupVar =
      "CPACK_COMPONENT_" + cmSystemTools::UpperCase(componentName) + "_GROUP";
    const char* _groupName = GetOption(groupVar);
    if (_groupName) {
      std::string groupName = _groupName;

      groupName =
        GetComponentPackageFileName(package_file_name, groupName, true);
      return groupName;
    }
  }

  return GetComponentPackageFileName(package_file_name, componentName, false);
}

bool cmCPackDragNDropGenerator::WriteLicense(
  cmGeneratedFileStream& outputStream, int licenseNumber,
  std::string licenseLanguage, const std::string& licenseFile,
  std::string* error)
{
  if (!licenseFile.empty() && !singleLicense) {
    licenseNumber = 5002;
    licenseLanguage = "English";
  }

  // License header
  outputStream << "data 'TEXT' (" << licenseNumber << ", \"" << licenseLanguage
               << "\") {\n";
  // License body
  std::string actual_license = !licenseFile.empty()
    ? licenseFile
    : (slaDirectory + "/" + licenseLanguage + ".license.txt");
  cmsys::ifstream license_ifs;
  license_ifs.open(actual_license.c_str());
  if (license_ifs.is_open()) {
    while (license_ifs.good()) {
      std::string line;
      std::getline(license_ifs, line);
      if (!line.empty()) {
        EscapeQuotesAndBackslashes(line);
        std::vector<std::string> lines;
        if (!this->BreakLongLine(line, lines, error)) {
          return false;
        }
        for (auto const& l : lines) {
          outputStream << "        \"" << l << "\"\n";
        }
      }
      outputStream << "        \"\\n\"\n";
    }
    license_ifs.close();
  }

  // End of License
  outputStream << "};\n\n";
  if (!licenseFile.empty() && !singleLicense) {
    outputStream << SLASTREnglish;
  } else {
    // Menu header
    outputStream << "resource 'STR#' (" << licenseNumber << ", \""
                 << licenseLanguage << "\") {\n";
    outputStream << "    {\n";

    // Menu body
    cmsys::ifstream menu_ifs;
    menu_ifs.open(
      (slaDirectory + "/" + licenseLanguage + ".menu.txt").c_str());
    if (menu_ifs.is_open()) {
      size_t lines_written = 0;
      while (menu_ifs.good()) {
        // Lines written from original file, not from broken up lines
        std::string line;
        std::getline(menu_ifs, line);
        if (!line.empty()) {
          EscapeQuotesAndBackslashes(line);
          std::vector<std::string> lines;
          if (!this->BreakLongLine(line, lines, error)) {
            return false;
          }
          for (size_t i = 0; i < lines.size(); ++i) {
            std::string comma;
            // We need a comma after every complete string,
            // but not on the very last line
            if (lines_written != 8 && i == lines.size() - 1) {
              comma = ",";
            } else {
              comma = "";
            }
            outputStream << "        \"" << lines[i] << "\"" << comma << "\n";
          }
          ++lines_written;
        }
      }
      menu_ifs.close();
    }

    // End of menu
    outputStream << "    }\n";
    outputStream << "};\n";
    outputStream << "\n";
  }

  return true;
}

bool cmCPackDragNDropGenerator::BreakLongLine(const std::string& line,
                                              std::vector<std::string>& lines,
                                              std::string* error)
{
  const size_t max_line_length = 512;
  for (size_t i = 0; i < line.size(); i += max_line_length) {
    size_t line_length = max_line_length;
    if (i + line_length > line.size()) {
      line_length = line.size() - i;
    } else {
      while (line_length > 0 && line[i + line_length - 1] != ' ') {
        line_length = line_length - 1;
      }
    }

    if (line_length == 0) {
      *error = "Please make sure there are no words "
               "(or character sequences not broken up by spaces or newlines) "
               "in your license file which are more than 512 characters long.";
      return false;
    }
    lines.push_back(line.substr(i, line_length));
  }
  return true;
}

void cmCPackDragNDropGenerator::EscapeQuotesAndBackslashes(std::string& line)
{
  std::string::size_type backslash_pos = line.find('\\');
  while (backslash_pos != std::string::npos) {
    line.replace(backslash_pos, 1, "\\\\");
    backslash_pos = line.find('\\', backslash_pos + 2);
  }

  std::string::size_type quote_pos = line.find('\"');
  while (quote_pos != std::string::npos) {
    line.replace(quote_pos, 1, "\\\"");
    quote_pos = line.find('\"', quote_pos + 2);
  }
}
