/* 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 "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.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;
  }

  const char* packageScript = this->GetOption("CPACK_EXTERNAL_PACKAGE_SCRIPT");
  if (packageScript && *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::GetErrorOccuredFlag() || !res) {
      return 0;
    }

    const char* builtPackagesStr =
      this->GetOption("CPACK_EXTERNAL_BUILT_PACKAGES");
    if (builtPackagesStr) {
      cmExpandList(builtPackagesStr, this->packageFileNames, false);
    }
  }

  return 1;
}

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

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

  return 1;
}

int cmCPackExternalGenerator::InstallProjectViaInstallScript(
  bool setDestDir, const std::string& tempInstallDirectory)
{
  if (this->StagingEnabled()) {
    return 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 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 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 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;
  }

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

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

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

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

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

  const char* defaultDirectoryPermissions =
    this->Parent->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
  if (defaultDirectoryPermissions && *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;
}
