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

#include <map>
#include <utility>
#include <vector>

#include <cm/memory>

#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>

#include "cmsys/FStream.hxx"

#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmList.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmValue.h"

int cmCPackExternalGenerator::InitializeInternal()
{
  this->SetOption("CPACK_EXTERNAL_KNOWN_VERSIONS", "1.0");

  if (!this->ReadListFile("Internal/CPack/CPackExternal.cmake")) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error while executing CPackExternal.cmake" << std::endl);
    return 0;
  }

  std::string major = this->GetOption("CPACK_EXTERNAL_SELECTED_MAJOR");
  if (major == "1") {
    this->Generator = cm::make_unique<cmCPackExternalVersion1Generator>(this);
  }

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

int cmCPackExternalGenerator::PackageFiles()
{
  Json::StreamWriterBuilder builder;
  builder["indentation"] = "  ";

  std::string filename = "package.json";
  if (!this->packageFileNames.empty()) {
    filename = this->packageFileNames[0];
  }

  cmsys::ofstream fout(filename.c_str());
  std::unique_ptr<Json::StreamWriter> jout(builder.newStreamWriter());

  Json::Value root(Json::objectValue);

  if (!this->Generator->WriteToJSON(root)) {
    return 0;
  }

  if (jout->write(root, &fout)) {
    return 0;
  }

  cmValue packageScript = this->GetOption("CPACK_EXTERNAL_PACKAGE_SCRIPT");
  if (cmNonempty(packageScript)) {
    if (!cmSystemTools::FileIsFullPath(*packageScript)) {
      cmCPackLogger(
        cmCPackLog::LOG_ERROR,
        "CPACK_EXTERNAL_PACKAGE_SCRIPT does not contain a full file path"
          << std::endl);
      return 0;
    }

    bool res = this->MakefileMap->ReadListFile(*packageScript);

    if (cmSystemTools::GetErrorOccurredFlag() || !res) {
      return 0;
    }

    cmValue builtPackages = this->GetOption("CPACK_EXTERNAL_BUILT_PACKAGES");
    if (builtPackages) {
      cmExpandList(builtPackages, this->packageFileNames);
    }
  }

  return 1;
}

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

int cmCPackExternalGenerator::InstallProjectViaInstallCommands(
  bool setDestDir, const std::string& tempInstallDirectory)
{
  if (this->StagingEnabled()) {
    return this->cmCPackGenerator::InstallProjectViaInstallCommands(
      setDestDir, tempInstallDirectory);
  }

  return 1;
}

int cmCPackExternalGenerator::InstallProjectViaInstallScript(
  bool setDestDir, const std::string& tempInstallDirectory)
{
  if (this->StagingEnabled()) {
    return this->cmCPackGenerator::InstallProjectViaInstallScript(
      setDestDir, tempInstallDirectory);
  }

  return 1;
}

int cmCPackExternalGenerator::InstallProjectViaInstalledDirectories(
  bool setDestDir, const std::string& tempInstallDirectory,
  const mode_t* default_dir_mode)
{
  if (this->StagingEnabled()) {
    return this->cmCPackGenerator::InstallProjectViaInstalledDirectories(
      setDestDir, tempInstallDirectory, default_dir_mode);
  }

  return 1;
}

int cmCPackExternalGenerator::RunPreinstallTarget(
  const std::string& installProjectName, const std::string& installDirectory,
  cmGlobalGenerator* globalGenerator, const std::string& buildConfig)
{
  if (this->StagingEnabled()) {
    return this->cmCPackGenerator::RunPreinstallTarget(
      installProjectName, installDirectory, globalGenerator, buildConfig);
  }

  return 1;
}

int cmCPackExternalGenerator::InstallCMakeProject(
  bool setDestDir, const std::string& installDirectory,
  const std::string& baseTempInstallDirectory, const mode_t* default_dir_mode,
  const std::string& component, bool componentInstall,
  const std::string& installSubDirectory, const std::string& buildConfig,
  std::string& absoluteDestFiles)
{
  if (this->StagingEnabled()) {
    return this->cmCPackGenerator::InstallCMakeProject(
      setDestDir, installDirectory, baseTempInstallDirectory, default_dir_mode,
      component, componentInstall, installSubDirectory, buildConfig,
      absoluteDestFiles);
  }

  return 1;
}

bool cmCPackExternalGenerator::StagingEnabled() const
{
  return !cmIsOff(this->GetOption("CPACK_EXTERNAL_ENABLE_STAGING"));
}

cmCPackExternalGenerator::cmCPackExternalVersionGenerator::
  cmCPackExternalVersionGenerator(cmCPackExternalGenerator* parent)
  : Parent(parent)
{
}

int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteVersion(
  Json::Value& root)
{
  root["formatVersionMajor"] = this->GetVersionMajor();
  root["formatVersionMinor"] = this->GetVersionMinor();

  return 1;
}

int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteToJSON(
  Json::Value& root)
{
  if (!this->WriteVersion(root)) {
    return 0;
  }

  cmValue packageName = this->Parent->GetOption("CPACK_PACKAGE_NAME");
  if (packageName) {
    root["packageName"] = *packageName;
  }

  cmValue packageVersion = this->Parent->GetOption("CPACK_PACKAGE_VERSION");
  if (packageVersion) {
    root["packageVersion"] = *packageVersion;
  }

  cmValue packageDescriptionFile =
    this->Parent->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE");
  if (packageDescriptionFile) {
    root["packageDescriptionFile"] = *packageDescriptionFile;
  }

  cmValue packageDescriptionSummary =
    this->Parent->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY");
  if (packageDescriptionSummary) {
    root["packageDescriptionSummary"] = *packageDescriptionSummary;
  }

  cmValue buildConfigCstr = this->Parent->GetOption("CPACK_BUILD_CONFIG");
  if (buildConfigCstr) {
    root["buildConfig"] = *buildConfigCstr;
  }

  cmValue defaultDirectoryPermissions =
    this->Parent->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
  if (cmNonempty(defaultDirectoryPermissions)) {
    root["defaultDirectoryPermissions"] = *defaultDirectoryPermissions;
  }
  if (cmIsInternallyOn(this->Parent->GetOption("CPACK_SET_DESTDIR"))) {
    root["setDestdir"] = true;
    root["packagingInstallPrefix"] =
      *this->Parent->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
  } else {
    root["setDestdir"] = false;
  }

  root["stripFiles"] = !cmIsOff(this->Parent->GetOption("CPACK_STRIP_FILES"));
  root["warnOnAbsoluteInstallDestination"] =
    this->Parent->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION");
  root["errorOnAbsoluteInstallDestination"] =
    this->Parent->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION");

  Json::Value& projects = root["projects"] = Json::Value(Json::arrayValue);
  for (auto& project : this->Parent->CMakeProjects) {
    Json::Value jsonProject(Json::objectValue);

    jsonProject["projectName"] = project.ProjectName;
    jsonProject["component"] = project.Component;
    jsonProject["directory"] = project.Directory;
    jsonProject["subDirectory"] = project.SubDirectory;

    Json::Value& installationTypes = jsonProject["installationTypes"] =
      Json::Value(Json::arrayValue);
    for (auto& installationType : project.InstallationTypes) {
      installationTypes.append(installationType->Name);
    }

    Json::Value& components = jsonProject["components"] =
      Json::Value(Json::arrayValue);
    for (auto& component : project.Components) {
      components.append(component->Name);
    }

    projects.append(jsonProject);
  }

  Json::Value& installationTypes = root["installationTypes"] =
    Json::Value(Json::objectValue);
  for (auto& installationType : this->Parent->InstallationTypes) {
    Json::Value& jsonInstallationType =
      installationTypes[installationType.first] =
        Json::Value(Json::objectValue);

    jsonInstallationType["name"] = installationType.second.Name;
    jsonInstallationType["displayName"] = installationType.second.DisplayName;
    jsonInstallationType["index"] = installationType.second.Index;
  }

  Json::Value& components = root["components"] =
    Json::Value(Json::objectValue);
  for (auto& component : this->Parent->Components) {
    Json::Value& jsonComponent = components[component.first] =
      Json::Value(Json::objectValue);

    jsonComponent["name"] = component.second.Name;
    jsonComponent["displayName"] = component.second.DisplayName;
    if (component.second.Group) {
      jsonComponent["group"] = component.second.Group->Name;
    }
    jsonComponent["isRequired"] = component.second.IsRequired;
    jsonComponent["isHidden"] = component.second.IsHidden;
    jsonComponent["isDisabledByDefault"] =
      component.second.IsDisabledByDefault;
    jsonComponent["isDownloaded"] = component.second.IsDownloaded;
    jsonComponent["description"] = component.second.Description;
    jsonComponent["archiveFile"] = component.second.ArchiveFile;

    Json::Value& cmpInstallationTypes = jsonComponent["installationTypes"] =
      Json::Value(Json::arrayValue);
    for (auto& installationType : component.second.InstallationTypes) {
      cmpInstallationTypes.append(installationType->Name);
    }

    Json::Value& dependencies = jsonComponent["dependencies"] =
      Json::Value(Json::arrayValue);
    for (auto& dep : component.second.Dependencies) {
      dependencies.append(dep->Name);
    }
  }

  Json::Value& groups = root["componentGroups"] =
    Json::Value(Json::objectValue);
  for (auto& group : this->Parent->ComponentGroups) {
    Json::Value& jsonGroup = groups[group.first] =
      Json::Value(Json::objectValue);

    jsonGroup["name"] = group.second.Name;
    jsonGroup["displayName"] = group.second.DisplayName;
    jsonGroup["description"] = group.second.Description;
    jsonGroup["isBold"] = group.second.IsBold;
    jsonGroup["isExpandedByDefault"] = group.second.IsExpandedByDefault;
    if (group.second.ParentGroup) {
      jsonGroup["parentGroup"] = group.second.ParentGroup->Name;
    }

    Json::Value& subgroups = jsonGroup["subgroups"] =
      Json::Value(Json::arrayValue);
    for (auto& subgroup : group.second.Subgroups) {
      subgroups.append(subgroup->Name);
    }

    Json::Value& groupComponents = jsonGroup["components"] =
      Json::Value(Json::arrayValue);
    for (auto& component : group.second.Components) {
      groupComponents.append(component->Name);
    }
  }

  return 1;
}
