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

#include <vector>

#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"

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

cmCPackPKGGenerator::~cmCPackPKGGenerator() = default;

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

int cmCPackPKGGenerator::InitializeInternal()
{
  cmCPackLogger(cmCPackLog::LOG_DEBUG,
                "cmCPackPKGGenerator::Initialize()" << std::endl);

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

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

  return component.ArchiveFile + ".pkg";
}

void cmCPackPKGGenerator::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.
  std::ostringstream choiceOut;
  cmXMLWriter xout(choiceOut, 1);
  xout.StartElement("choices-outline");

  // Emit the outline for the groups
  for (auto const& group : this->ComponentGroups) {
    if (group.second.ParentGroup == nullptr) {
      CreateChoiceOutline(group.second, xout);
    }
  }

  // Emit the outline for the non-grouped components
  for (auto const& comp : this->Components) {
    if (!comp.second.Group) {
      xout.StartElement("line");
      xout.Attribute("choice", comp.first + "Choice");
      xout.Content(""); // Avoid self-closing tag.
      xout.EndElement();
    }
  }
  if (!this->PostFlightComponent.Name.empty()) {
    xout.StartElement("line");
    xout.Attribute("choice", PostFlightComponent.Name + "Choice");
    xout.Content(""); // Avoid self-closing tag.
    xout.EndElement();
  }
  xout.EndElement(); // choices-outline>

  // Create the actual choices
  for (auto const& group : this->ComponentGroups) {
    CreateChoice(group.second, xout);
  }
  for (auto const& comp : this->Components) {
    CreateChoice(comp.second, xout);
  }

  if (!this->PostFlightComponent.Name.empty()) {
    CreateChoice(PostFlightComponent, xout);
  }

  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, distributionFile);
}

void cmCPackPKGGenerator::CreateChoiceOutline(
  const cmCPackComponentGroup& group, cmXMLWriter& xout)
{
  xout.StartElement("line");
  xout.Attribute("choice", group.Name + "Choice");
  for (cmCPackComponentGroup* subgroup : group.Subgroups) {
    CreateChoiceOutline(*subgroup, xout);
  }

  for (cmCPackComponent* comp : group.Components) {
    xout.StartElement("line");
    xout.Attribute("choice", comp->Name + "Choice");
    xout.Content(""); // Avoid self-closing tag.
    xout.EndElement();
  }
  xout.EndElement();
}

void cmCPackPKGGenerator::CreateChoice(const cmCPackComponentGroup& group,
                                       cmXMLWriter& xout)
{
  xout.StartElement("choice");
  xout.Attribute("id", group.Name + "Choice");
  xout.Attribute("title", group.DisplayName);
  xout.Attribute("start_selected", "true");
  xout.Attribute("start_enabled", "true");
  xout.Attribute("start_visible", "true");
  if (!group.Description.empty()) {
    xout.Attribute("description", group.Description);
  }
  xout.EndElement();
}

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

  xout.StartElement("choice");
  xout.Attribute("id", component.Name + "Choice");
  xout.Attribute("title", component.DisplayName);
  xout.Attribute(
    "start_selected",
    component.IsDisabledByDefault && !component.IsRequired ? "false" : "true");
  xout.Attribute("start_enabled", component.IsRequired ? "false" : "true");
  xout.Attribute("start_visible", component.IsHidden ? "false" : "true");
  if (!component.Description.empty()) {
    xout.Attribute("description", 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.
    std::ostringstream selected("my.choice.selected", std::ios_base::ate);
    std::set<const cmCPackComponent*> visited;
    AddDependencyAttributes(component, visited, selected);
    visited.clear();
    AddReverseDependencyAttributes(component, visited, selected);
    xout.Attribute("selected", selected.str());
  }
  xout.StartElement("pkg-ref");
  xout.Attribute("id", packageId);
  xout.EndElement(); // pkg-ref
  xout.EndElement(); // choice

  // 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;
  dirName += this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
  unsigned long installedSize = component.GetInstalledSizeInKbytes(dirName);

  xout.StartElement("pkg-ref");
  xout.Attribute("id", packageId);
  xout.Attribute("version", this->GetOption("CPACK_PACKAGE_VERSION"));
  xout.Attribute("installKBytes", installedSize);
  xout.Attribute("auth", "Admin");
  xout.Attribute("onConclusion", "None");
  if (component.IsDownloaded) {
    xout.Content(this->GetOption("CPACK_DOWNLOAD_SITE"));
    xout.Content(this->GetPackageName(component));
  } else {
    xout.Content("file:./");
    xout.Content(cmSystemTools::EncodeURL(relativePackageLocation,
                                          /*escapeSlashes=*/false));
  }
  xout.EndElement(); // pkg-ref
}

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

  for (cmCPackComponent* depend : component.Dependencies) {
    out << " && choices['" << depend->Name << "Choice'].selected";
    AddDependencyAttributes(*depend, visited, out);
  }
}

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

  for (cmCPackComponent* depend : component.ReverseDependencies) {
    out << " || choices['" << depend->Name << "Choice'].selected";
    AddReverseDependencyAttributes(*depend, visited, out);
  }
}

bool cmCPackPKGGenerator::CopyCreateResourceFile(const std::string& name,
                                                 const std::string& dirName)
{
  std::string uname = cmSystemTools::UpperCase(name);
  std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname;
  const char* inFileName = this->GetOption(cpackVar);
  if (!inFileName) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "CPack option: " << cpackVar.c_str()
                                   << " not specified. It should point to "
                                   << (!name.empty() ? name : "<empty>")
                                   << ".rtf, " << name << ".html, or " << name
                                   << ".txt file" << std::endl);
    return false;
  }
  if (!cmSystemTools::FileExists(inFileName)) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Cannot find " << (!name.empty() ? name : "<empty>")
                                 << " 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",
                  (name + ext).c_str());

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

bool cmCPackPKGGenerator::CopyResourcePlistFile(const std::string& name,
                                                const char* outName)
{
  if (!outName) {
    outName = name.c_str();
  }

  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 << " to " << destFileName
                                   << std::endl);
  this->ConfigureFile(inFileName, destFileName);
  return true;
}

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

  return 1;
}
