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

#include <map>
#include <sstream>
#include <utility>

#include <cm/memory>
#include <cm/optional>
#include <cmext/algorithm>
#include <cmext/string_view>

#include "cmsys/RegularExpression.hxx"

#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
#include "cmBuildSbomGenerator.h"
#include "cmCryptoHash.h"
#include "cmDiagnosticContext.h"
#include "cmDiagnostics.h"
#include "cmExecutionStatus.h"
#include "cmExperimental.h"
#include "cmExportBuildAndroidMKGenerator.h"
#include "cmExportBuildCMakeConfigGenerator.h"
#include "cmExportBuildFileGenerator.h"
#include "cmExportBuildPackageInfoGenerator.h"
#include "cmExportSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPackageInfoArguments.h"
#include "cmPolicies.h"
#include "cmRange.h"
#include "cmSbomArguments.h"
#include "cmStringAlgorithms.h"
#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetTypes.h"
#include "cmValue.h"

#if defined(__HAIKU__)
#  include <FindDirectory.h>
#  include <StorageDefs.h>
#endif

#if defined(_WIN32) && !defined(__CYGWIN__)
#  include <windows.h>
#endif

static void StorePackageRegistry(cmMakefile& mf, std::string const& package,
                                 char const* content, char const* hash);

static cm::optional<cmExportSet*> GetExportSet(std::string const& name,
                                               cmGlobalGenerator* generator,
                                               cmExecutionStatus& status)
{
  cmExportSetMap& setMap = generator->GetExportSets();
  auto const it = setMap.find(name);
  if (it == setMap.end()) {
    status.SetError(cmStrCat("Export set \""_s, name, "\" not found."_s));
    return cm::nullopt;
  }
  return &it->second;
}

static void AddExportGenerator(
  cmMakefile& makefile, cmGlobalGenerator* globalGenerator,
  std::unique_ptr<cmExportBuildFileGenerator> exportGenerator,
  std::string const& fileName, cmExportSet* exportSet,
  std::string const& cxxModulesDirectory)
{
  exportGenerator->SetExportFile(fileName.c_str());
  exportGenerator->SetCxxModuleDirectory(cxxModulesDirectory);
  if (exportSet) {
    exportGenerator->SetExportSet(exportSet);
  }
  std::vector<std::string> configurationTypes =
    makefile.GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);

  for (std::string const& ct : configurationTypes) {
    exportGenerator->AddConfiguration(ct);
  }
  if (exportSet) {
    globalGenerator->AddBuildExportExportSet(exportGenerator.get());
  }
  makefile.AddExportBuildFileGenerator(std::move(exportGenerator));
}

static bool ValidateExportableTarget(std::string const& name, cmMakefile& mf,
                                     cmGlobalGenerator* gg,
                                     cmExecutionStatus& status)
{
  if (mf.IsAlias(name)) {
    status.SetError(cmStrCat("given ALIAS target \"", name,
                             "\" which may not be exported."));
    return false;
  }
  cmTarget const* target = gg->FindTarget(name);
  if (!target) {
    status.SetError(cmStrCat("given target \"", name,
                             "\" which is not built by this project."));
    return false;
  }
  if (target->GetType() == cm::TargetType::UTILITY) {
    status.SetError(cmStrCat("given custom target \"", name,
                             "\" which may not be exported."));
    return false;
  }
  return true;
}

static bool HandleTargetsMode(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
{
  struct Arguments
  {
    cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Targets;
    ArgumentParser::NonEmpty<std::string> ExportSetName;
    ArgumentParser::NonEmpty<std::string> Namespace;
    ArgumentParser::NonEmpty<std::string> Filename;
    ArgumentParser::NonEmpty<std::string> CxxModulesDirectory;
    ArgumentParser::NonEmpty<std::string> AndroidMKFile;

    bool Append = false;
    bool ExportOld = false;
  };

  auto parser =
    cmArgumentParser<Arguments>{}
      .Bind("NAMESPACE"_s, &Arguments::Namespace)
      .Bind("FILE"_s, &Arguments::Filename)
      .Bind("CXX_MODULES_DIRECTORY"_s, &Arguments::CxxModulesDirectory)
      .Bind("TARGETS"_s, &Arguments::Targets)
      .Bind("APPEND"_s, &Arguments::Append)
      .Bind("ANDROID_MK"_s, &Arguments::AndroidMKFile)
      .Bind("EXPORT_LINK_INTERFACE_LIBRARIES"_s, &Arguments::ExportOld);

  std::vector<std::string> unknownArgs;
  Arguments arguments = parser.Parse(args, &unknownArgs);

  if (!unknownArgs.empty()) {
    status.SetError(
      cmStrCat("Unknown argument: \"", unknownArgs.front(), "\"."));
    return false;
  }

  std::string fname;
  bool android = false;
  if (!arguments.AndroidMKFile.empty()) {
    fname = arguments.AndroidMKFile;
    android = true;
  } else if (arguments.Filename.empty()) {
    fname = arguments.ExportSetName + ".cmake";
  } else {
    // Make sure the file has a .cmake extension.
    if (!cmHasSuffix(arguments.Filename, ".cmake"_s)) {
      std::ostringstream e;
      e << "FILE option given filename \"" << arguments.Filename
        << "\" which does not have an extension of \".cmake\".\n";
      status.SetError(e.str());
      return false;
    }
    fname = arguments.Filename;
  }

  cmMakefile& mf = status.GetMakefile();

  // Get the file to write.
  if (cmSystemTools::FileIsFullPath(fname)) {
    if (!mf.CanIWriteThisFile(fname)) {
      std::ostringstream e;
      e << "FILE option given filename \"" << fname
        << "\" which is in the source tree.\n";
      status.SetError(e.str());
      return false;
    }
  } else {
    // Interpret relative paths with respect to the current build dir.
    std::string const& dir = mf.GetCurrentBinaryDirectory();
    fname = cmStrCat(dir, '/', fname);
  }

  std::vector<cmExportBuildFileGenerator::TargetExport> targets;
  cmGlobalGenerator* gg = mf.GetGlobalGenerator();

  for (std::string const& currentTarget : *arguments.Targets) {
    if (!ValidateExportableTarget(currentTarget, mf, gg, status)) {
      return false;
    }
    targets.emplace_back(currentTarget, std::string{});
  }
  if (arguments.Append) {
    if (cmExportBuildFileGenerator* ebfg = gg->GetExportedTargetsFile(fname)) {
      ebfg->AppendTargets(targets);
      return true;
    }
  }

  // if cmExportBuildFileGenerator is already defined for the file
  // and APPEND is not specified, if CMP0103 is OLD ignore previous definition
  // else raise an error
  if (gg->GetExportedTargetsFile(fname)) {
    switch (mf.GetPolicyStatus(cmPolicies::CMP0103)) {
      case cmPolicies::WARN:
        mf.IssuePolicyWarning(
          cmPolicies::CMP0103, {},
          cmStrCat("export() command already specified for the file\n  ",
                   arguments.Filename, "\nDid you miss 'APPEND' keyword?"));
        CM_FALLTHROUGH;
      case cmPolicies::OLD:
        break;
      default:
        status.SetError(cmStrCat("command already specified for the file\n  ",
                                 arguments.Filename,
                                 "\nDid you miss 'APPEND' keyword?"));
        return false;
    }
  }

  cmDiagnosticContext context = cmExportBuildFileGenerator::CaptureContext(mf);
  std::unique_ptr<cmExportBuildFileGenerator> ebfg = nullptr;
  if (android) {
    auto ebag =
      cm::make_unique<cmExportBuildAndroidMKGenerator>(std::move(context));
    ebag->SetNamespace(arguments.Namespace);
    ebag->SetAppendMode(arguments.Append);
    ebfg = std::move(ebag);
  } else {
    auto ebcg =
      cm::make_unique<cmExportBuildCMakeConfigGenerator>(std::move(context));
    ebcg->SetNamespace(arguments.Namespace);
    ebcg->SetAppendMode(arguments.Append);
    ebcg->SetExportOld(arguments.ExportOld);
    ebfg = std::move(ebcg);
  }

  ebfg->SetExportFile(fname.c_str());
  ebfg->SetCxxModuleDirectory(arguments.CxxModulesDirectory);
  ebfg->SetTargets(targets);
  std::vector<std::string> configurationTypes =
    mf.GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);

  for (std::string const& ct : configurationTypes) {
    ebfg->AddConfiguration(ct);
  }
  gg->AddBuildExportSet(ebfg.get());
  mf.AddExportBuildFileGenerator(std::move(ebfg));

  return true;
}

static bool HandleExportMode(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  struct ExportArguments : public ArgumentParser::ParseResult
  {
    ArgumentParser::NonEmpty<std::string> ExportSetName;
    ArgumentParser::MaybeEmpty<std::string> Namespace;
    ArgumentParser::NonEmpty<std::string> Filename;
    ArgumentParser::NonEmpty<std::string> CxxModulesDirectory;
    bool ExportPackageDependencies = false;
  };

  auto parser =
    cmArgumentParser<ExportArguments>{}
      .Bind("EXPORT"_s, &ExportArguments::ExportSetName)
      .Bind("NAMESPACE"_s, &ExportArguments::Namespace)
      .Bind("FILE"_s, &ExportArguments::Filename)
      .Bind("CXX_MODULES_DIRECTORY"_s, &ExportArguments::CxxModulesDirectory);

  if (cmExperimental::HasSupportEnabled(
        status.GetMakefile(),
        cmExperimental::Feature::ExportPackageDependencies)) {
    parser.Bind("EXPORT_PACKAGE_DEPENDENCIES"_s,
                &ExportArguments::ExportPackageDependencies);
  }

  std::vector<std::string> unknownArgs;
  ExportArguments arguments = parser.Parse(args, &unknownArgs);

  cmMakefile& mf = status.GetMakefile();
  cmGlobalGenerator* gg = mf.GetGlobalGenerator();

  if (!arguments.Check(args[0], &unknownArgs, status)) {
    cmPolicies::PolicyStatus const p =
      status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0208);
    if (!unknownArgs.empty() || p == cmPolicies::NEW) {
      return false;
    }
    if (p == cmPolicies::WARN) {
      status.GetMakefile().IssueDiagnostic(
        cmDiagnostics::CMD_AUTHOR, cmStrCat("export "_s, status.GetError()));
      status.GetMakefile().IssuePolicyWarning(cmPolicies::CMP0208);
    }
  }

  std::string fname;
  if (arguments.Filename.empty()) {
    fname = arguments.ExportSetName + ".cmake";
  } else {
    if (!cmHasSuffix(arguments.Filename, ".cmake"_s)) {
      std::ostringstream e;
      e << "FILE option given filename \"" << arguments.Filename
        << "\" which does not have an extension of \".cmake\".\n";
      status.SetError(e.str());
      return false;
    }
    fname = arguments.Filename;
  }

  if (cmSystemTools::FileIsFullPath(fname)) {
    if (!mf.CanIWriteThisFile(fname)) {
      std::ostringstream e;
      e << "FILE option given filename \"" << fname
        << "\" which is in the source tree.\n";
      status.SetError(e.str());
      return false;
    }
  } else {
    // Interpret relative paths with respect to the current build dir.
    std::string const& dir = mf.GetCurrentBinaryDirectory();
    fname = cmStrCat(dir, '/', fname);
  }

  cm::optional<cmExportSet*> const exportSet =
    GetExportSet(arguments.ExportSetName, gg, status);
  if (!exportSet) {
    return false;
  }

  // Set up export file generation.
  auto ebcg = cm::make_unique<cmExportBuildCMakeConfigGenerator>(
    cmExportBuildFileGenerator::CaptureContext(mf));
  ebcg->SetNamespace(arguments.Namespace);
  ebcg->SetExportPackageDependencies(arguments.ExportPackageDependencies);

  AddExportGenerator(mf, gg, std::move(ebcg), fname, *exportSet,
                     arguments.CxxModulesDirectory);
  return true;
}

template <typename ArgumentsType, typename GeneratorType>
static bool HandleSpecialExportMode(std::vector<std::string> const& args,
                                    cmExecutionStatus& status)
{
  struct ExportArguments
    : public ArgumentsType
    , public ArgumentParser::ParseResult
  {
    ArgumentParser::NonEmpty<std::string> ExportSetName;
    ArgumentParser::NonEmpty<std::string> CxxModulesDirectory;

    using ArgumentsType::Check;
    using ArgumentParser::ParseResult::Check;
  };

  auto parser =
    cmArgumentParser<ExportArguments>{}
      .Bind("EXPORT"_s, &ExportArguments::ExportSetName)
      .Bind("CXX_MODULES_DIRECTORY"_s, &ExportArguments::CxxModulesDirectory);
  ArgumentsType::Bind(parser);

  std::vector<std::string> unknownArgs;
  ExportArguments arguments = parser.Parse(args, &unknownArgs);

  if (!arguments.Check(args[0], &unknownArgs, status)) {
    return false;
  }

  if (arguments.ExportSetName.empty()) {
    status.SetError(cmStrCat(args[0], " missing EXPORT."));
    return false;
  }

  if (!arguments.Check(status) || !arguments.SetMetadataFromProject(status)) {
    return false;
  }

  cmMakefile& mf = status.GetMakefile();
  cmGlobalGenerator* gg = mf.GetGlobalGenerator();

  std::string const& dir =
    arguments.GetDefaultDestination(mf.GetCurrentBinaryDirectory());
  std::string const fname = cmStrCat(dir, '/', arguments.GetPackageFileName());

  if (gg->GetExportedTargetsFile(fname)) {
    status.SetError(cmStrCat("command already specified for the file "_s,
                             cmSystemTools::GetFilenameNameView(fname), '.'));
    return false;
  }

  // Look up the export set
  cm::optional<cmExportSet*> const exportSet =
    GetExportSet(arguments.ExportSetName, gg, status);
  if (!exportSet) {
    return false;
  }

  // Create the export build generator
  auto ebpg = cm::make_unique<GeneratorType>(
    arguments, cmExportBuildFileGenerator::CaptureContext(mf));
  AddExportGenerator(mf, gg, std::move(ebpg), fname, *exportSet,
                     arguments.CxxModulesDirectory);
  return true;
}

static bool HandlePackageInfoMode(std::vector<std::string> const& args,
                                  cmExecutionStatus& status)
{
  using arg_t = cmPackageInfoArguments;
  using gen_t = cmExportBuildPackageInfoGenerator;
  return HandleSpecialExportMode<arg_t, gen_t>(args, status);
}

static bool HandleSbomMode(std::vector<std::string> const& args,
                           cmExecutionStatus& status)
{
  if (!cmExperimental::HasSupportEnabled(
        status.GetMakefile(), cmExperimental::Feature::GenerateSbom)) {
    status.SetError("does not recognize sub-command SBOM");
    return false;
  }

  struct SbomExportArguments
    : public cmSbomArguments
    , public ArgumentParser::ParseResult
  {
    ArgumentParser::NonEmpty<std::vector<std::string>> ExportSetNames;

    using cmSbomArguments::Check;
    using ArgumentParser::ParseResult::Check;
  };

  auto parser = cmArgumentParser<SbomExportArguments>{};
  cmSbomArguments::Bind(parser);
  parser.Bind("EXPORTS"_s, &SbomExportArguments::ExportSetNames);

  std::vector<std::string> unknownArgs;
  SbomExportArguments arguments = parser.Parse(args, &unknownArgs);

  if (!arguments.Check(args[0], &unknownArgs, status)) {
    return false;
  }

  if (arguments.ExportSetNames.empty()) {
    status.SetError(cmStrCat(args[0], " missing EXPORTS."));
    return false;
  }

  if (!arguments.Check(status) || !arguments.SetMetadataFromProject(status)) {
    return false;
  }

  cmMakefile& mf = status.GetMakefile();
  cmGlobalGenerator* gg = mf.GetGlobalGenerator();

  std::string const dir =
    arguments.GetDefaultDestination(mf.GetCurrentBinaryDirectory());
  std::string const fpath = cmStrCat(dir, '/', arguments.GetPackageName());

  if (gg->IsBuildSbomFile(fpath)) {
    status.SetError(cmStrCat("SBOM command already specified for the file "_s,
                             cmSystemTools::GetFilenameNameView(fpath), '.'));
    return false;
  }

  std::vector<cmExportSet*> sets;
  sets.reserve(arguments.ExportSetNames.size());
  for (std::string const& name : arguments.ExportSetNames) {
    cm::optional<cmExportSet*> const exportSet =
      GetExportSet(name, gg, status);
    if (!exportSet) {
      return false;
    }
    sets.push_back(*exportSet);
  }

  auto builder = cm::make_unique<cmBuildSbomGenerator>(arguments, sets, fpath);
  cmBuildSbomGenerator* rawPtr = builder.get();
  mf.AddBuildSbomGenerator(std::move(builder));
  gg->AddBuildSbomGenerator(rawPtr);
  return true;
}

static bool HandleSetupMode(std::vector<std::string> const& args,
                            cmExecutionStatus& status)
{
  struct SetupArguments
  {
    ArgumentParser::NonEmpty<std::string> ExportSetName;
    ArgumentParser::NonEmpty<std::string> CxxModulesDirectory;
    std::vector<std::vector<std::string>> PackageDependencyArgs;
    std::vector<std::vector<std::string>> TargetArgs;
  };

  auto parser = cmArgumentParser<SetupArguments>{};
  parser.Bind("SETUP"_s, &SetupArguments::ExportSetName);
  if (cmExperimental::HasSupportEnabled(
        status.GetMakefile(),
        cmExperimental::Feature::ExportPackageDependencies)) {
    parser.Bind("PACKAGE_DEPENDENCY"_s,
                &SetupArguments::PackageDependencyArgs);
  }
  parser.Bind("TARGET"_s, &SetupArguments::TargetArgs);

  std::vector<std::string> unknownArgs;
  SetupArguments arguments = parser.Parse(args, &unknownArgs);

  if (!unknownArgs.empty()) {
    status.SetError("SETUP given unknown argument: \"" + unknownArgs.front() +
                    "\".");
    return false;
  }

  cmMakefile& mf = status.GetMakefile();
  cmGlobalGenerator* gg = mf.GetGlobalGenerator();

  cmExportSetMap& setMap = gg->GetExportSets();
  auto& exportSet = setMap[arguments.ExportSetName];

  struct PackageDependencyArguments
  {
    std::string Enabled;
    ArgumentParser::MaybeEmpty<std::vector<std::string>> ExtraArgs;
  };

  auto packageDependencyParser =
    cmArgumentParser<PackageDependencyArguments>{}
      .Bind("ENABLED"_s, &PackageDependencyArguments::Enabled)
      .Bind("EXTRA_ARGS"_s, &PackageDependencyArguments::ExtraArgs);

  for (auto const& packageDependencyArgs : arguments.PackageDependencyArgs) {
    if (packageDependencyArgs.empty()) {
      continue;
    }
    PackageDependencyArguments const packageDependencyArguments =
      packageDependencyParser.Parse(
        cmMakeRange(packageDependencyArgs).advance(1), &unknownArgs);

    if (!unknownArgs.empty()) {
      status.SetError(cmStrCat("PACKAGE_DEPENDENCY given unknown argument: \"",
                               unknownArgs.front(), "\"."));
      return false;
    }
    auto& packageDependency =
      exportSet.GetPackageDependencyForSetup(packageDependencyArgs.front());
    if (!packageDependencyArguments.Enabled.empty()) {
      if (packageDependencyArguments.Enabled == "AUTO") {
        packageDependency.Enabled =
          cmExportSet::PackageDependencyExportEnabled::Auto;
      } else if (cmIsOff(packageDependencyArguments.Enabled)) {
        packageDependency.Enabled =
          cmExportSet::PackageDependencyExportEnabled::Off;
      } else if (cmIsOn(packageDependencyArguments.Enabled)) {
        packageDependency.Enabled =
          cmExportSet::PackageDependencyExportEnabled::On;
      } else {
        status.SetError(
          cmStrCat("Invalid enable setting for package dependency: \"",
                   packageDependencyArguments.Enabled, '"'));
        return false;
      }
    }
    cm::append(packageDependency.ExtraArguments,
               packageDependencyArguments.ExtraArgs);
  }

  struct TargetArguments
  {
    std::string XcFrameworkLocation;
  };

  auto targetParser = cmArgumentParser<TargetArguments>{}.Bind(
    "XCFRAMEWORK_LOCATION"_s, &TargetArguments::XcFrameworkLocation);

  for (auto const& targetArgs : arguments.TargetArgs) {
    if (targetArgs.empty()) {
      continue;
    }
    TargetArguments const targetArguments =
      targetParser.Parse(cmMakeRange(targetArgs).advance(1), &unknownArgs);

    if (!unknownArgs.empty()) {
      status.SetError(cmStrCat("TARGET given unknown argument: \"",
                               unknownArgs.front(), "\"."));
      return false;
    }
    exportSet.SetXcFrameworkLocation(targetArgs.front(),
                                     targetArguments.XcFrameworkLocation);
  }
  return true;
}

static bool HandlePackageMode(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
{
  // Parse PACKAGE mode arguments.
  enum Doing
  {
    DoingNone,
    DoingPackage
  };
  Doing doing = DoingPackage;
  std::string package;
  for (unsigned int i = 1; i < args.size(); ++i) {
    if (doing == DoingPackage) {
      package = args[i];
      doing = DoingNone;
    } else {
      std::ostringstream e;
      e << "PACKAGE given unknown argument: " << args[i];
      status.SetError(e.str());
      return false;
    }
  }

  // Verify the package name.
  if (package.empty()) {
    status.SetError("PACKAGE must be given a package name.");
    return false;
  }
  char const* packageExpr = "^[A-Za-z0-9_.-]+$";
  cmsys::RegularExpression packageRegex(packageExpr);
  if (!packageRegex.find(package)) {
    std::ostringstream e;
    e << "PACKAGE given invalid package name \"" << package << "\".  "
      << "Package names must match \"" << packageExpr << "\".";
    status.SetError(e.str());
    return false;
  }

  cmMakefile& mf = status.GetMakefile();

  // CMP0090 decides both the default and what variable changes it.
  switch (mf.GetPolicyStatus(cmPolicies::CMP0090)) {
    case cmPolicies::WARN:
      CM_FALLTHROUGH;
    case cmPolicies::OLD:
      // Default is to export, but can be disabled.
      if (mf.IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY")) {
        return true;
      }
      break;
    case cmPolicies::NEW:
      // Default is to not export, but can be enabled.
      if (!mf.IsOn("CMAKE_EXPORT_PACKAGE_REGISTRY")) {
        return true;
      }
      break;
  }

  // We store the current build directory in the registry as a value
  // named by a hash of its own content.  This is deterministic and is
  // unique with high probability.
  std::string const& outDir = mf.GetCurrentBinaryDirectory();
  cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
  std::string hash = hasher.HashString(outDir);
  StorePackageRegistry(mf, package, outDir.c_str(), hash.c_str());

  return true;
}

#if defined(_WIN32) && !defined(__CYGWIN__)

static void ReportRegistryError(cmMakefile& mf, std::string const& msg,
                                std::string const& key, long err)
{
  std::ostringstream e;
  e << msg << "\n"
    << "  HKEY_CURRENT_USER\\" << key << "\n";
  wchar_t winmsg[1024];
  if (FormatMessageW(
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, err,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), winmsg, 1024, 0) > 0) {
    e << "Windows reported:\n"
      << "  " << cmsys::Encoding::ToNarrow(winmsg);
  }
  mf.IssueMessage(MessageType::WARNING, e.str());
}

static void StorePackageRegistry(cmMakefile& mf, std::string const& package,
                                 char const* content, char const* hash)
{
  std::string key = cmStrCat("Software\\Kitware\\CMake\\Packages\\", package);
  HKEY hKey;
  LONG err =
    RegCreateKeyExW(HKEY_CURRENT_USER, cmsys::Encoding::ToWide(key).c_str(), 0,
                    0, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, 0, &hKey, 0);
  if (err != ERROR_SUCCESS) {
    ReportRegistryError(mf, "Cannot create/open registry key", key, err);
    return;
  }

  std::wstring wcontent = cmsys::Encoding::ToWide(content);
  err =
    RegSetValueExW(hKey, cmsys::Encoding::ToWide(hash).c_str(), 0, REG_SZ,
                   (BYTE const*)wcontent.c_str(),
                   static_cast<DWORD>(wcontent.size() + 1) * sizeof(wchar_t));
  RegCloseKey(hKey);
  if (err != ERROR_SUCCESS) {
    std::ostringstream msg;
    msg << "Cannot set registry value \"" << hash << "\" under key";
    ReportRegistryError(mf, msg.str(), key, err);
    return;
  }
}
#else
static void StorePackageRegistry(cmMakefile& mf, std::string const& package,
                                 char const* content, char const* hash)
{
#  if defined(__HAIKU__)
  char dir[B_PATH_NAME_LENGTH];
  if (find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, dir, sizeof(dir)) !=
      B_OK) {
    return;
  }
  std::string fname = cmStrCat(dir, "/cmake/packages/", package);
#  else
  std::string fname;
  if (!cmSystemTools::GetEnv("HOME", fname)) {
    return;
  }
  cmSystemTools::ConvertToUnixSlashes(fname);
  fname += "/.cmake/packages/";
  fname += package;
#  endif
  cmSystemTools::MakeDirectory(fname);
  fname += "/";
  fname += hash;
  if (!cmSystemTools::FileExists(fname)) {
    cmGeneratedFileStream entry(fname, true);
    if (entry) {
      entry << content << "\n";
    } else {
      mf.IssueMessage(MessageType::WARNING,
                      cmStrCat("Cannot create package registry file:\n"
                               "  ",
                               fname, '\n',
                               cmSystemTools::GetLastSystemError(), '\n'));
    }
  }
}
#endif

bool cmExportCommand(std::vector<std::string> const& args,
                     cmExecutionStatus& status)
{
  if (args.empty()) {
    return true;
  }

  static cmSubcommandTable const subcommand{
    { "TARGETS"_s, HandleTargetsMode },
    { "EXPORT"_s, HandleExportMode },
    { "SETUP"_s, HandleSetupMode },
    { "PACKAGE"_s, HandlePackageMode },
    { "PACKAGE_INFO"_s, HandlePackageInfoMode },
    { "SBOM"_s, HandleSbomMode },
  };

  return subcommand(args[0], args, status);
}
