/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmCPackPackageMakerGenerator.h"

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

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

//----------------------------------------------------------------------
cmCPackPackageMakerGenerator::cmCPackPackageMakerGenerator()
{
  this->PackageMakerVersion = 0.0;
  this->PackageCompatibilityVersion = 10.4;
}

//----------------------------------------------------------------------
cmCPackPackageMakerGenerator::~cmCPackPackageMakerGenerator()
{
}

//----------------------------------------------------------------------
bool cmCPackPackageMakerGenerator::SupportsComponentInstallation() const
{
  return this->PackageCompatibilityVersion >= 10.4;
}

//----------------------------------------------------------------------
int cmCPackPackageMakerGenerator::CopyInstallScript(const char* resdir,
                                                    const char* script,
                                                    const char* name)
{
  std::string dst = resdir;
  dst += "/";
  dst += name;
  cmSystemTools::CopyFileAlways(script, dst.c_str());
  cmSystemTools::SetPermissions(dst.c_str(),0777);
  cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                "copy script : " << script << "\ninto " << dst.c_str() << 
                std::endl);

  return 1;
}

//----------------------------------------------------------------------
int cmCPackPackageMakerGenerator::CompressFiles(const char* outFileName,
  const char* toplevel,
  const std::vector<std::string>& files)
{
  (void) files; // TODO: Fix api to not need files.
  (void) toplevel; // TODO: Use toplevel

  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";
    }


  // Create directory structure
  std::string preflightDirName = resDir + "/PreFlight";
  std::string postflightDirName = resDir + "/PostFlight";
  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 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.c_str() << std::endl);
      return 0;
      }
    }
  if(!postflight)
    {
    if ( !cmsys::SystemTools::MakeDirectory(postflightDirName.c_str()))
      {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
                    "Problem creating installer directory: "
                    << postflightDirName.c_str() << 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.c_str(),
                            preflight,
                            "preflight");
    }
  if(postflight)
    {
    this->CopyInstallScript(resDir.c_str(),
                            postflight,
                            "postflight");
    }
  if(postupgrade)
    {
    this->CopyInstallScript(resDir.c_str(),
                            postupgrade,
                            "postupgrade");
    }

  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.c_str() << 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 >= 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 < 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.c_str())
       || !this->CopyCreateResourceFile("ReadMe", resDir.c_str())
       || !this->CopyCreateResourceFile("Welcome", resDir.c_str())
       || !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.
    cmOStringStream 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";
  cmOStringStream dmgCmd;
  dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
    << "\" create -ov -format UDZO -srcfolder \"" << packageDirFileName
    << "\" \"" << outFileName << "\"";
  std::string output;
  int retVal = 1;
  int numTries = 4;
  bool res;
  while(numTries > 0)
    {
    res = cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output,
                                          &retVal, 0, this->GeneratorVerbose, 
                                          0);
    if(res && retVal)
      {
      numTries = -1;
      }
    numTries--;
    }
  if ( !res || retVal )
    {
    cmGeneratedFileStream ofs(tmpFile.c_str());
    ofs << "# Run command: " << dmgCmd.str().c_str() << std::endl
      << "# Output:" << std::endl
      << output.c_str() << std::endl;
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running hdiutil command: "
      << dmgCmd.str().c_str() << std::endl
      << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
    return 0;
    }

  return 1;
}

//----------------------------------------------------------------------
int cmCPackPackageMakerGenerator::InitializeInternal()
{
  cmCPackLogger(cmCPackLog::LOG_DEBUG,
    "cmCPackPackageMakerGenerator::Initialize()" << std::endl);
  this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
  std::vector<std::string> path;
  std::string pkgPath
    = "/Developer/Applications/Utilities/PackageMaker.app/Contents";
  std::string versionFile = pkgPath + "/version.plist";
  if ( !cmSystemTools::FileExists(versionFile.c_str()) )
    {
    pkgPath = "/Developer/Applications/PackageMaker.app/Contents";
    std::string newVersionFile = pkgPath + "/version.plist";
    if ( !cmSystemTools::FileExists(newVersionFile.c_str()) )
      {
      cmCPackLogger(cmCPackLog::LOG_ERROR,
        "Cannot find PackageMaker compiler version file: "
        << versionFile.c_str() << " or " << newVersionFile.c_str()
        << std::endl);
      return 0;
      }
    versionFile = newVersionFile;
    }
  std::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.c_str() << 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)
    {
    this->PackageCompatibilityVersion = atof(packageCompat);  
    }
  else if (this->GetOption("CPACK_DOWNLOAD_SITE"))
    {
    this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.5");
    this->PackageCompatibilityVersion = 10.5;
    }
  else if (this->GetOption("CPACK_COMPONENTS_ALL"))
    {
    this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.4");
    this->PackageCompatibilityVersion = 10.4;
    }
  else
    {
    this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.3");
    this->PackageCompatibilityVersion = 10.3;
    }

  pkgPath += "/MacOS";
  path.push_back(pkgPath);
  pkgPath = cmSystemTools::FindProgram("PackageMaker", path, false);
  if ( pkgPath.empty() )
    {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find PackageMaker compiler"
      << std::endl);
    return 0;
    }
  this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", pkgPath.c_str());
  pkgPath = cmSystemTools::FindProgram("hdiutil", path, 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::CopyCreateResourceFile(const char* name,
                                                          const char* dirName)
{
  std::string uname = cmSystemTools::UpperCase(name);
  std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname;
  const char* inFileName = this->GetOption(cpackVar.c_str());
  if ( !inFileName )
    {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack option: " << cpackVar.c_str()
                  << " not specified. It should point to " 
                  << (name ? name : "(NULL)")
                  << ".rtf, " << name
                  << ".html, or " << name << ".txt file" << std::endl);
    return false;
    }
  if ( !cmSystemTools::FileExists(inFileName) )
    {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find " 
                  << (name ? name : "(NULL)")
                  << " resource file: " << inFileName << std::endl);
    return false;
    }
  std::string ext = cmSystemTools::GetFilenameLastExtension(inFileName);
  if ( ext != ".rtfd" && ext != ".rtf" && ext != ".html" && ext != ".txt" )
    {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Bad file extension specified: "
      << ext << ". Currently only .rtfd, .rtf, .html, and .txt files allowed."
      << std::endl);
    return false;
    }

  std::string destFileName = dirName;
  destFileName += '/';
  destFileName += name + ext;

  // Set this so that distribution.dist gets the right name (without
  // the path).
  this->SetOption(("CPACK_RESOURCE_FILE_" + uname + "_NOPATH").c_str(),
                  (name + ext).c_str());

  cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " 
                << (inFileName ? inFileName : "(NULL)")
                << " to " << destFileName.c_str() << std::endl);
  this->ConfigureFile(inFileName, destFileName.c_str());
  return true;
}

bool cmCPackPackageMakerGenerator::CopyResourcePlistFile(const char* name,
                                                         const char* outName)
{
  if (!outName)
    {
    outName = name;
    }

  std::string inFName = "CPack.";
  inFName += name;
  inFName += ".in";
  std::string inFileName = this->FindTemplate(inFName.c_str());
  if ( inFileName.empty() )
    {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find input file: "
      << inFName << std::endl);
    return false;
    }

  std::string destFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  destFileName += "/";
  destFileName += outName;

  cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
    << inFileName.c_str() << " to " << destFileName.c_str() << std::endl);
  this->ConfigureFile(inFileName.c_str(), destFileName.c_str());
  return true;
}

//----------------------------------------------------------------------
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, &retVal, 0, 
                                             this->GeneratorVerbose, 0);
  cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Done running package maker"
    << std::endl);
  if ( !res || retVal )
    {
    cmGeneratedFileStream ofs(tmpFile.c_str());
    ofs << "# Run command: " << command << std::endl
      << "# Output:" << std::endl
      << output.c_str() << std::endl;
    cmCPackLogger(cmCPackLog::LOG_ERROR,
      "Problem running PackageMaker command: " << command
      << std::endl << "Please check " << tmpFile.c_str() << " 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;
}

//----------------------------------------------------------------------
std::string 
cmCPackPackageMakerGenerator::GetPackageName(const cmCPackComponent& component)
{
  if (component.ArchiveFile.empty())
    {
    std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
    packagesDir += ".dummy";
    cmOStringStream out;
    out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir)
        << "-" << component.Name << ".pkg";
    return out.str();
    }
  else
    {
    return component.ArchiveFile + ".pkg";
    }
}

//----------------------------------------------------------------------
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
  cmOStringStream pkgCmd;

  if (this->PackageCompatibilityVersion < 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";
    std::ofstream out(descriptionFile.c_str());
    out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl
        << "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\""
        << "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" << std::endl
        << "<plist version=\"1.4\">" << std::endl
        << "<dict>" << std::endl
        << "  <key>IFPkgDescriptionTitle</key>" << std::endl
        << "  <string>" << component.DisplayName << "</string>" << std::endl
        << "  <key>IFPkgDescriptionVersion</key>" << std::endl
        << "  <string>" << this->GetOption("CPACK_PACKAGE_VERSION") 
        << "</string>" << std::endl
        << "  <key>IFPkgDescriptionDescription</key>" << std::endl
        << "  <string>" + this->EscapeForXML(component.Description) 
        << "</string>" << std::endl
        << "</dict>" << std::endl
        << "</plist>" << std::endl;
    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);
}

//----------------------------------------------------------------------
void 
cmCPackPackageMakerGenerator::
WriteDistributionFile(const char* metapackageFile)
{
  std::string distributionTemplate 
    = this->FindTemplate("CPack.distribution.dist.in");
  if ( distributionTemplate.empty() )
    {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find input file: "
      << distributionTemplate << std::endl);
    return;
    }

  std::string distributionFile = metapackageFile;
  distributionFile += "/Contents/distribution.dist";

  // Create the choice outline, which provides a tree-based view of
  // the components in their groups.
  cmOStringStream choiceOut;
  choiceOut << "<choices-outline>" << std::endl;

  // Emit the outline for the groups
  std::map<std::string, cmCPackComponentGroup>::iterator groupIt;
  for (groupIt = this->ComponentGroups.begin(); 
       groupIt != this->ComponentGroups.end(); 
       ++groupIt)
    {
    if (groupIt->second.ParentGroup == 0)
      {
      CreateChoiceOutline(groupIt->second, choiceOut);
      }
    }

  // Emit the outline for the non-grouped components
  std::map<std::string, cmCPackComponent>::iterator compIt;
  for (compIt = this->Components.begin(); compIt != this->Components.end();
       ++compIt)
    {
    if (!compIt->second.Group)
      {
      choiceOut << "<line choice=\"" << compIt->first << "Choice\"></line>"
                << std::endl;
      }
    }
  choiceOut << "</choices-outline>" << std::endl;

  // Create the actual choices
  for (groupIt = this->ComponentGroups.begin(); 
       groupIt != this->ComponentGroups.end(); 
       ++groupIt)
    {
    CreateChoice(groupIt->second, choiceOut);
    }
  for (compIt = this->Components.begin(); compIt != this->Components.end();
       ++compIt)
    {
    CreateChoice(compIt->second, choiceOut);
    }
  this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str());

  // Create the distribution.dist file in the metapackage to turn it
  // into a distribution package.
  this->ConfigureFile(distributionTemplate.c_str(), 
                      distributionFile.c_str());
}

//----------------------------------------------------------------------
void
cmCPackPackageMakerGenerator::
CreateChoiceOutline(const cmCPackComponentGroup& group, cmOStringStream& out)
{
  out << "<line choice=\"" << group.Name << "Choice\">" << std::endl;
  std::vector<cmCPackComponentGroup*>::const_iterator groupIt;
  for (groupIt = group.Subgroups.begin(); groupIt != group.Subgroups.end();
       ++groupIt)
    {
    CreateChoiceOutline(**groupIt, out);
    }

  std::vector<cmCPackComponent*>::const_iterator compIt;
  for (compIt = group.Components.begin(); compIt != group.Components.end();
       ++compIt)
    {
    out << "  <line choice=\"" << (*compIt)->Name << "Choice\"></line>"
        << std::endl;
    }
  out << "</line>" << std::endl;
}

//----------------------------------------------------------------------
void 
cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponentGroup& group,
                                           cmOStringStream& out)
{
  out << "<choice id=\"" << group.Name << "Choice\" " 
      << "title=\"" << group.DisplayName << "\" "
      << "start_selected=\"true\" " 
      << "start_enabled=\"true\" "
      << "start_visible=\"true\" ";
  if (!group.Description.empty())
    {
    out << "description=\"" << EscapeForXML(group.Description)
        << "\"";
    }
  out << "></choice>" << std::endl;
}

//----------------------------------------------------------------------
void 
cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component,
                                           cmOStringStream& out)
{
  std::string packageId = "com.";
  packageId += this->GetOption("CPACK_PACKAGE_VENDOR");
  packageId += '.'; 
  packageId += this->GetOption("CPACK_PACKAGE_NAME");
  packageId += '.';
  packageId += component.Name;

  out << "<choice id=\"" << component.Name << "Choice\" " 
      << "title=\"" << component.DisplayName << "\" "
      << "start_selected=\"" 
      << (component.IsDisabledByDefault && 
          !component.IsRequired? "false" : "true")
      << "\" "
      << "start_enabled=\""
      << (component.IsRequired? "false" : "true")
      << "\" "
      << "start_visible=\"" << (component.IsHidden? "false" : "true") << "\" ";
  if (!component.Description.empty())
    {
    out << "description=\"" << EscapeForXML(component.Description)
        << "\" ";
    }
  if (!component.Dependencies.empty() ||
      !component.ReverseDependencies.empty())
    {
    // The "selected" expression is evaluated each time any choice is
    // selected, for all choices *except* the one that the user
    // selected. A component is marked selected if it has been
    // selected (my.choice.selected in Javascript) and all of the
    // components it depends on have been selected (transitively) or
    // if any of the components that depend on it have been selected
    // (transitively). Assume that we have components A, B, C, D, and
    // E, where each component depends on the previous component (B
    // depends on A, C depends on B, D depends on C, and E depends on
    // D). The expression we build for the component C will be
    //   my.choice.selected && B && A || D || E
    // This way, selecting C will automatically select everything it depends
    // on (B and A), while selecting something that depends on C--either D
    // or E--will automatically cause C to get selected.
    out << "selected=\"my.choice.selected";
    std::set<const cmCPackComponent *> visited;
    AddDependencyAttributes(component, visited, out);
    visited.clear();
    AddReverseDependencyAttributes(component, visited, out);
    out << "\"";
    }
  out << ">" << std::endl;
  out << "  <pkg-ref id=\"" << packageId << "\"></pkg-ref>" << std::endl;
  out << "</choice>" << std::endl;

  // Create a description of the package associated with this
  // component.
  std::string relativePackageLocation = "Contents/Packages/";
  relativePackageLocation += this->GetPackageName(component);

  // Determine the installed size of the package.
  std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
  dirName += '/';
  dirName += component.Name;
  unsigned long installedSize 
    = component.GetInstalledSizeInKbytes(dirName.c_str());

  out << "<pkg-ref id=\"" << packageId << "\" "
      << "version=\"" << this->GetOption("CPACK_PACKAGE_VERSION") << "\" "
      << "installKBytes=\"" << installedSize << "\" "
      << "auth=\"Admin\" onConclusion=\"None\">";
  if (component.IsDownloaded)
    {
    out << this->GetOption("CPACK_DOWNLOAD_SITE") 
        << this->GetPackageName(component);
    }
  else
    {
    out << "file:./" << relativePackageLocation;
    }
  out << "</pkg-ref>" << std::endl;
}

//----------------------------------------------------------------------
void 
cmCPackPackageMakerGenerator::
AddDependencyAttributes(const cmCPackComponent& component, 
                        std::set<const cmCPackComponent *>& visited,
                        cmOStringStream& out)
{
  if (visited.find(&component) != visited.end())
    {
    return;
    }
  visited.insert(&component);

  std::vector<cmCPackComponent *>::const_iterator dependIt;
  for (dependIt = component.Dependencies.begin();
       dependIt != component.Dependencies.end();
       ++dependIt)
    {
    out << " &amp;&amp; choices['" << 
      (*dependIt)->Name << "Choice'].selected";
    AddDependencyAttributes(**dependIt, visited, out);
    }
}

//----------------------------------------------------------------------
void 
cmCPackPackageMakerGenerator::
AddReverseDependencyAttributes(const cmCPackComponent& component, 
                               std::set<const cmCPackComponent *>& visited,
                               cmOStringStream& out)
{
  if (visited.find(&component) != visited.end())
    {
    return;
    }
  visited.insert(&component);

  std::vector<cmCPackComponent *>::const_iterator dependIt;
  for (dependIt = component.ReverseDependencies.begin();
       dependIt != component.ReverseDependencies.end();
       ++dependIt)
    {
    out << " || choices['" << (*dependIt)->Name << "Choice'].selected";
    AddReverseDependencyAttributes(**dependIt, visited, out);
    }
}

//----------------------------------------------------------------------
std::string cmCPackPackageMakerGenerator::EscapeForXML(std::string str)
{
  cmSystemTools::ReplaceString(str, "&", "&amp;");
  cmSystemTools::ReplaceString(str, "<", "&lt;");
  cmSystemTools::ReplaceString(str, ">", "&gt;");
  cmSystemTools::ReplaceString(str, "\"", "&quot;");
  return str;
}
