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

#include <cstring>
#include <set>
#include <sstream>
#include <utility>
#include <vector>

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

#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"

#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVSSetupHelper.h"
#include "cmake.h"

#ifndef IMAGE_FILE_MACHINE_ARM64
#  define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian
#endif

static bool VSIsWow64()
{
  BOOL isWow64 = false;
  return IsWow64Process(GetCurrentProcess(), &isWow64) && isWow64;
}

static bool VSIsArm64Host()
{
  typedef BOOL(WINAPI * CM_ISWOW64PROCESS2)(
    HANDLE hProcess, USHORT * pProcessMachine, USHORT * pNativeMachine);

#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#  define CM_VS_GCC_DIAGNOSTIC_PUSHED
#  pragma GCC diagnostic push
#  pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
  static const CM_ISWOW64PROCESS2 s_IsWow64Process2Impl =
    (CM_ISWOW64PROCESS2)GetProcAddress(
      GetModuleHandleW(L"api-ms-win-core-wow64-l1-1-1.dll"),
      "IsWow64Process2");
#ifdef CM_VS_GCC_DIAGNOSTIC_PUSHED
#  pragma GCC diagnostic pop
#  undef CM_VS_GCC_DIAGNOSTIC_PUSHED
#endif

  USHORT processMachine;
  USHORT nativeMachine;

  return s_IsWow64Process2Impl &&
    s_IsWow64Process2Impl(GetCurrentProcess(), &processMachine,
                          &nativeMachine) &&
    nativeMachine == IMAGE_FILE_MACHINE_ARM64;
}

static bool VSHasDotNETFrameworkArm64()
{
  std::string dotNetArm64;
  return cmSystemTools::ReadRegistryValue(
    R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework;InstallRootArm64)",
    dotNetArm64, cmSystemTools::KeyWOW64_64);
}

static bool VSIsWindows11OrGreater()
{
  cmSystemTools::WindowsVersion const windowsVersion =
    cmSystemTools::GetWindowsVersion();
  return (windowsVersion.dwMajorVersion > 10 ||
          (windowsVersion.dwMajorVersion == 10 &&
           windowsVersion.dwMinorVersion > 0) ||
          (windowsVersion.dwMajorVersion == 10 &&
           windowsVersion.dwMinorVersion == 0 &&
           windowsVersion.dwBuildNumber >= 22000));
}

static std::string VSHostPlatformName()
{
  if (VSIsArm64Host()) {
    return "ARM64";
  }
  if (VSIsWow64()) {
    return "x64";
  }
#if defined(_M_ARM)
  return "ARM";
#elif defined(_M_IA64)
  return "Itanium";
#elif defined(_WIN64)
  return "x64";
#else
  return "Win32";
#endif
}

static std::string VSHostArchitecture(
  cmGlobalVisualStudioGenerator::VSVersion v)
{
  if (VSIsArm64Host()) {
    return v >= cmGlobalVisualStudioGenerator::VSVersion::VS17 ? "ARM64" : "";
  }
  if (VSIsWow64()) {
    return "x64";
  }
#if defined(_M_ARM)
  return "";
#elif defined(_M_IA64)
  return "";
#elif defined(_WIN64)
  return "x64";
#else
  return "x86";
#endif
}

static unsigned int VSVersionToMajor(
  cmGlobalVisualStudioGenerator::VSVersion v)
{
  switch (v) {
    case cmGlobalVisualStudioGenerator::VSVersion::VS14:
      return 14;
    case cmGlobalVisualStudioGenerator::VSVersion::VS15:
      return 15;
    case cmGlobalVisualStudioGenerator::VSVersion::VS16:
      return 16;
    case cmGlobalVisualStudioGenerator::VSVersion::VS17:
      return 17;
    case cmGlobalVisualStudioGenerator::VSVersion::VS18:
      return 18;
  }
  return 0;
}

static char const* VSVersionToToolset(
  cmGlobalVisualStudioGenerator::VSVersion v)
{
  switch (v) {
    case cmGlobalVisualStudioGenerator::VSVersion::VS14:
      return "v140";
    case cmGlobalVisualStudioGenerator::VSVersion::VS15:
      return "v141";
    case cmGlobalVisualStudioGenerator::VSVersion::VS16:
      return "v142";
    case cmGlobalVisualStudioGenerator::VSVersion::VS17:
      return "v143";
    case cmGlobalVisualStudioGenerator::VSVersion::VS18:
      return "v145";
  }
  return "";
}

static std::string VSVersionToMajorString(
  cmGlobalVisualStudioGenerator::VSVersion v)
{
  switch (v) {
    case cmGlobalVisualStudioGenerator::VSVersion::VS14:
      return "14";
    case cmGlobalVisualStudioGenerator::VSVersion::VS15:
      return "15";
    case cmGlobalVisualStudioGenerator::VSVersion::VS16:
      return "16";
    case cmGlobalVisualStudioGenerator::VSVersion::VS17:
      return "17";
    case cmGlobalVisualStudioGenerator::VSVersion::VS18:
      return "18";
  }
  return "";
}

static char const* VSVersionToAndroidToolset(
  cmGlobalVisualStudioGenerator::VSVersion v)
{
  switch (v) {
    case cmGlobalVisualStudioGenerator::VSVersion::VS14:
      return "Clang_3_8";
    case cmGlobalVisualStudioGenerator::VSVersion::VS15:
    case cmGlobalVisualStudioGenerator::VSVersion::VS16:
    case cmGlobalVisualStudioGenerator::VSVersion::VS17:
    case cmGlobalVisualStudioGenerator::VSVersion::VS18:
      return "Clang_5_0";
  }
  return "";
}

static char const vs15generatorName[] = "Visual Studio 15 2017";

// Map generator name without year to name with year.
static char const* cmVS15GenName(std::string const& name, std::string& genName)
{
  if (strncmp(name.c_str(), vs15generatorName,
              sizeof(vs15generatorName) - 6) != 0) {
    return nullptr;
  }
  char const* p = name.c_str() + sizeof(vs15generatorName) - 6;
  if (cmHasLiteralPrefix(p, " 2017")) {
    p += 5;
  }
  genName = cmStrCat(vs15generatorName, p);
  return p;
}

class cmGlobalVisualStudioVersionedGenerator::Factory15
  : public cmGlobalGeneratorFactory
{
public:
  std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
    std::string const& name, cmake* cm) const override
  {
    std::string genName;
    char const* p = cmVS15GenName(name, genName);
    if (!p) {
      return std::unique_ptr<cmGlobalGenerator>();
    }
    if (!*p) {
      return std::unique_ptr<cmGlobalGenerator>(
        new cmGlobalVisualStudioVersionedGenerator(
          cmGlobalVisualStudioGenerator::VSVersion::VS15, cm, genName));
    }
    return std::unique_ptr<cmGlobalGenerator>();
  }

  cmDocumentationEntry GetDocumentation() const override
  {
    return { std::string(vs15generatorName),
             "Generates Visual Studio 2017 project files.  "
             "Use -A option to specify architecture." };
  }

  std::vector<std::string> GetGeneratorNames() const override
  {
    std::vector<std::string> names;
    names.push_back(vs15generatorName);
    return names;
  }

  bool SupportsToolset() const override { return true; }
  bool SupportsPlatform() const override { return true; }

  std::vector<std::string> GetKnownPlatforms() const override
  {
    std::vector<std::string> platforms;
    platforms.emplace_back("x64");
    platforms.emplace_back("Win32");
    platforms.emplace_back("ARM");
    platforms.emplace_back("ARM64");
    return platforms;
  }

  std::string GetDefaultPlatformName() const override { return "Win32"; }
};

std::unique_ptr<cmGlobalGeneratorFactory>
cmGlobalVisualStudioVersionedGenerator::NewFactory15()
{
  return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory15);
}

static char const vs16generatorName[] = "Visual Studio 16 2019";
static char const vs17generatorName[] = "Visual Studio 17 2022";
static char const vs18generatorName[] = "Visual Studio 18 2026";

// Map generator name without year to name with year.
static char const* cmVS16GenName(std::string const& name, std::string& genName)
{
  if (strncmp(name.c_str(), vs16generatorName,
              sizeof(vs16generatorName) - 6) != 0) {
    return nullptr;
  }
  char const* p = name.c_str() + sizeof(vs16generatorName) - 6;
  if (cmHasLiteralPrefix(p, " 2019")) {
    p += 5;
  }
  genName = cmStrCat(vs16generatorName, p);
  return p;
}

static char const* cmVS17GenName(std::string const& name, std::string& genName)
{
  if (strncmp(name.c_str(), vs17generatorName,
              sizeof(vs17generatorName) - 6) != 0) {
    return nullptr;
  }
  char const* p = name.c_str() + sizeof(vs17generatorName) - 6;
  if (cmHasLiteralPrefix(p, " 2022")) {
    p += 5;
  }
  genName = cmStrCat(vs17generatorName, p);
  return p;
}

static char const* cmVS18GenName(std::string const& name, std::string& genName)
{
  if (strncmp(name.c_str(), vs18generatorName,
              sizeof(vs18generatorName) - 6) != 0) {
    return nullptr;
  }
  char const* p = name.c_str() + sizeof(vs18generatorName) - 6;
  if (cmHasLiteralPrefix(p, " 2026")) {
    p += 5;
  }
  genName = cmStrCat(vs18generatorName, p);
  return p;
}

class cmGlobalVisualStudioVersionedGenerator::Factory16
  : public cmGlobalGeneratorFactory
{
public:
  std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
    std::string const& name, cmake* cm) const override
  {
    std::string genName;
    char const* p = cmVS16GenName(name, genName);
    if (!p) {
      return std::unique_ptr<cmGlobalGenerator>();
    }
    if (!*p) {
      return std::unique_ptr<cmGlobalGenerator>(
        new cmGlobalVisualStudioVersionedGenerator(
          cmGlobalVisualStudioGenerator::VSVersion::VS16, cm, genName));
    }
    return std::unique_ptr<cmGlobalGenerator>();
  }

  cmDocumentationEntry GetDocumentation() const override
  {
    return { std::string(vs16generatorName),
             "Generates Visual Studio 2019 project files.  "
             "Use -A option to specify architecture." };
  }

  std::vector<std::string> GetGeneratorNames() const override
  {
    std::vector<std::string> names;
    names.push_back(vs16generatorName);
    return names;
  }

  bool SupportsToolset() const override { return true; }
  bool SupportsPlatform() const override { return true; }

  std::vector<std::string> GetKnownPlatforms() const override
  {
    std::vector<std::string> platforms;
    platforms.emplace_back("x64");
    platforms.emplace_back("Win32");
    platforms.emplace_back("ARM");
    platforms.emplace_back("ARM64");
    platforms.emplace_back("ARM64EC");
    return platforms;
  }

  std::string GetDefaultPlatformName() const override
  {
    return VSHostPlatformName();
  }
};

std::unique_ptr<cmGlobalGeneratorFactory>
cmGlobalVisualStudioVersionedGenerator::NewFactory16()
{
  return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory16);
}

class cmGlobalVisualStudioVersionedGenerator::Factory17
  : public cmGlobalGeneratorFactory
{
public:
  std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
    std::string const& name, cmake* cm) const override
  {
    std::string genName;
    char const* p = cmVS17GenName(name, genName);
    if (!p) {
      return std::unique_ptr<cmGlobalGenerator>();
    }
    if (!*p) {
      return std::unique_ptr<cmGlobalGenerator>(
        new cmGlobalVisualStudioVersionedGenerator(
          cmGlobalVisualStudioGenerator::VSVersion::VS17, cm, genName));
    }
    return std::unique_ptr<cmGlobalGenerator>();
  }

  cmDocumentationEntry GetDocumentation() const override
  {
    return { std::string(vs17generatorName),
             "Generates Visual Studio 2022 project files.  "
             "Use -A option to specify architecture." };
  }

  std::vector<std::string> GetGeneratorNames() const override
  {
    std::vector<std::string> names;
    names.push_back(vs17generatorName);
    return names;
  }

  bool SupportsToolset() const override { return true; }
  bool SupportsPlatform() const override { return true; }

  std::vector<std::string> GetKnownPlatforms() const override
  {
    std::vector<std::string> platforms;
    platforms.emplace_back("x64");
    platforms.emplace_back("Win32");
    platforms.emplace_back("ARM");
    platforms.emplace_back("ARM64");
    platforms.emplace_back("ARM64EC");
    return platforms;
  }

  std::string GetDefaultPlatformName() const override
  {
    return VSHostPlatformName();
  }
};

std::unique_ptr<cmGlobalGeneratorFactory>
cmGlobalVisualStudioVersionedGenerator::NewFactory17()
{
  return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory17);
}

class cmGlobalVisualStudioVersionedGenerator::Factory18
  : public cmGlobalGeneratorFactory
{
public:
  std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
    std::string const& name, cmake* cm) const override
  {
    std::string genName;
    char const* p = cmVS18GenName(name, genName);
    if (!p) {
      return std::unique_ptr<cmGlobalGenerator>();
    }
    if (!*p) {
      return std::unique_ptr<cmGlobalGenerator>(
        new cmGlobalVisualStudioVersionedGenerator(
          cmGlobalVisualStudioGenerator::VSVersion::VS18, cm, genName));
    }
    return std::unique_ptr<cmGlobalGenerator>();
  }

  cmDocumentationEntry GetDocumentation() const override
  {
    return { std::string(vs18generatorName),
             "Generates Visual Studio 2026 project files.  "
             "Use -A option to specify architecture." };
  }

  std::vector<std::string> GetGeneratorNames() const override
  {
    std::vector<std::string> names;
    names.push_back(vs18generatorName);
    return names;
  }

  bool SupportsToolset() const override { return true; }
  bool SupportsPlatform() const override { return true; }

  std::vector<std::string> GetKnownPlatforms() const override
  {
    std::vector<std::string> platforms;
    platforms.emplace_back("x64");
    platforms.emplace_back("Win32");
    platforms.emplace_back("ARM");
    platforms.emplace_back("ARM64");
    platforms.emplace_back("ARM64EC");
    return platforms;
  }

  std::string GetDefaultPlatformName() const override
  {
    return VSHostPlatformName();
  }
};

std::unique_ptr<cmGlobalGeneratorFactory>
cmGlobalVisualStudioVersionedGenerator::NewFactory18()
{
  return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory18);
}

cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator(
  VSVersion version, cmake* cm, std::string const& name)
  : cmGlobalVisualStudio14Generator(cm, name)
  , vsSetupAPIHelper(VSVersionToMajor(version))
{
  this->Version = version;
  this->ExpressEdition = false;
  this->DefaultPlatformToolset = VSVersionToToolset(this->Version);
  this->DefaultAndroidToolset = VSVersionToAndroidToolset(this->Version);
  this->DefaultCLFlagTableName = VSVersionToToolset(this->Version);
  this->DefaultCSharpFlagTableName = VSVersionToToolset(this->Version);
  this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version);
  if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16) {
    this->DefaultPlatformName = VSHostPlatformName();
    this->DefaultPlatformToolsetHostArchitecture =
      VSHostArchitecture(this->Version);
  }
  if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS17) {
    // FIXME: Search for an existing framework?  Under '%ProgramFiles(x86)%',
    // see 'Reference Assemblies\Microsoft\Framework\.NETFramework'.
    // Use a version installed by VS 2022 without a separate component.
    this->DefaultTargetFrameworkVersion = "v4.7.2";
  }
  if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS18) {
    this->DefaultToolsetFortran = "ifx";
  }
}

bool cmGlobalVisualStudioVersionedGenerator::MatchesGeneratorName(
  std::string const& name) const
{
  std::string genName;
  switch (this->Version) {
    case cmGlobalVisualStudioGenerator::VSVersion::VS14:
      break;
    case cmGlobalVisualStudioGenerator::VSVersion::VS15:
      if (cmVS15GenName(name, genName)) {
        return genName == this->GetName();
      }
      break;
    case cmGlobalVisualStudioGenerator::VSVersion::VS16:
      if (cmVS16GenName(name, genName)) {
        return genName == this->GetName();
      }
      break;
    case cmGlobalVisualStudioGenerator::VSVersion::VS17:
      if (cmVS17GenName(name, genName)) {
        return genName == this->GetName();
      }
      break;
    case cmGlobalVisualStudioGenerator::VSVersion::VS18:
      if (cmVS18GenName(name, genName)) {
        return genName == this->GetName();
      }
      break;
  }
  return false;
}

bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
  std::string const& i, cmMakefile* mf)
{
  if (this->LastGeneratorInstanceString &&
      i == *(this->LastGeneratorInstanceString)) {
    this->SetVSVersionVar(mf);
    return true;
  }

  if (!this->ParseGeneratorInstance(i, mf)) {
    return false;
  }

  if (!this->GeneratorInstanceVersion.empty()) {
    std::string const majorStr = VSVersionToMajorString(this->Version);
    cmsys::RegularExpression versionRegex(
      cmStrCat('^', majorStr, R"(\.[0-9]+\.[0-9]+\.[0-9]+$)"));
    if (!versionRegex.find(this->GeneratorInstanceVersion)) {
      mf->IssueMessage(
        MessageType::FATAL_ERROR,
        cmStrCat("Generator\n"
                 "  ",
                 this->GetName(),
                 "\n"
                 "given instance specification\n"
                 "  ",
                 i,
                 "\n"
                 "but the version field is not 4 integer components"
                 " starting in ",
                 majorStr, '.'));
      return false;
    }
  }

  std::string vsInstance;
  if (!i.empty()) {
    vsInstance = i;
    if (!this->vsSetupAPIHelper.SetVSInstance(
          this->GeneratorInstance, this->GeneratorInstanceVersion)) {
      std::ostringstream e;
      /* clang-format off */
      e <<
        "Generator\n"
        "  " << this->GetName() << "\n"
        "could not find specified instance of Visual Studio:\n"
        "  " << i;
      /* clang-format on */
      if (!this->GeneratorInstance.empty() &&
          this->GeneratorInstanceVersion.empty() &&
          cmSystemTools::FileIsDirectory(this->GeneratorInstance)) {
        e << "\n"
             "The directory exists, but the instance is not known to the "
             "Visual Studio Installer, and no 'version=' field was given.";
      }
      mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
      return false;
    }
  } else if (!this->vsSetupAPIHelper.GetVSInstanceInfo(vsInstance)) {
    mf->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat("Generator\n"
               "  ",
               this->GetName(),
               "\n"
               "could not find any instance of Visual Studio.\n"));
    return false;
  }

  // Save the selected instance persistently.
  std::string genInstance = mf->GetSafeDefinition("CMAKE_GENERATOR_INSTANCE");
  if (vsInstance != genInstance) {
    this->CMakeInstance->AddCacheEntry("CMAKE_GENERATOR_INSTANCE", vsInstance,
                                       "Generator instance identifier.",
                                       cmStateEnums::INTERNAL);
  }

  this->SetVSVersionVar(mf);

  // The selected instance may have a different MSBuild than previously found.
  this->MSBuildCommandInitialized = false;

  this->LastGeneratorInstanceString = i;

  return true;
}

bool cmGlobalVisualStudioVersionedGenerator::ParseGeneratorInstance(
  std::string const& is, cmMakefile* mf)
{
  this->GeneratorInstance.clear();
  this->GeneratorInstanceVersion.clear();

  std::vector<std::string> const fields =
    cmTokenize(is, ',', cmTokenizerMode::New);
  if (fields.empty()) {
    return true;
  }

  auto fi = fields.begin();
  // The first field may be the VS instance.
  if (fi->find('=') == fi->npos) {
    this->GeneratorInstance = *fi;
    ++fi;
  }

  std::set<std::string> handled;

  // The rest of the fields must be key=value pairs.
  for (; fi != fields.end(); ++fi) {
    std::string::size_type pos = fi->find('=');
    if (pos == fi->npos) {
      mf->IssueMessage(
        MessageType::FATAL_ERROR,
        cmStrCat("Generator\n"
                 "  ",
                 this->GetName(),
                 "\n"
                 "given instance specification\n"
                 "  ",
                 is,
                 "\n"
                 "that contains a field after the first ',' with no '='."));
      return false;
    }
    std::string const key = fi->substr(0, pos);
    std::string const value = fi->substr(pos + 1);
    if (!handled.insert(key).second) {
      mf->IssueMessage(MessageType::FATAL_ERROR,
                       cmStrCat("Generator\n"
                                "  ",
                                this->GetName(),
                                "\n"
                                "given instance specification\n"
                                "  ",
                                is,
                                "\n"
                                "that contains duplicate field key '",
                                key, "'."));
      return false;
    }
    if (!this->ProcessGeneratorInstanceField(key, value)) {
      mf->IssueMessage(MessageType::FATAL_ERROR,
                       cmStrCat("Generator\n"
                                "  ",
                                this->GetName(),
                                "\n"
                                "given instance specification\n"
                                "  ",
                                is,
                                "\n"
                                "that contains invalid field '",
                                *fi, "'."));
      return false;
    }
  }

  return true;
}

void cmGlobalVisualStudioVersionedGenerator::SetVSVersionVar(cmMakefile* mf)
{
  if (cm::optional<std::string> vsVer = this->GetVSInstanceVersion()) {
    mf->AddDefinition("CMAKE_VS_VERSION_BUILD_NUMBER", *vsVer);
  }
}

bool cmGlobalVisualStudioVersionedGenerator::ProcessGeneratorInstanceField(
  std::string const& key, std::string const& value)
{
  if (key == "version"_s) {
    this->GeneratorInstanceVersion = value;
    return true;
  }
  return false;
}

bool cmGlobalVisualStudioVersionedGenerator::GetVSInstance(
  std::string& dir) const
{
  return vsSetupAPIHelper.GetVSInstanceInfo(dir);
}

cm::optional<std::string>
cmGlobalVisualStudioVersionedGenerator::GetVSInstanceVersion() const
{
  cm::optional<std::string> result;
  std::string vsInstanceVersion;
  if (vsSetupAPIHelper.GetVSInstanceVersion(vsInstanceVersion)) {
    result = vsInstanceVersion;
  }
  return result;
}

bool cmGlobalVisualStudioVersionedGenerator::IsStdOutEncodingSupported() const
{
  // Supported from Visual Studio 16.7 Preview 3.
  if (this->Version > cmGlobalVisualStudioGenerator::VSVersion::VS16) {
    return true;
  }
  if (this->Version < cmGlobalVisualStudioGenerator::VSVersion::VS16) {
    return false;
  }
  static std::string const vsVer16_7_P2 = "16.7.30128.36";
  cm::optional<std::string> vsVer = this->GetVSInstanceVersion();
  return (vsVer &&
          cmSystemTools::VersionCompareGreaterEq(*vsVer, vsVer16_7_P2));
}

bool cmGlobalVisualStudioVersionedGenerator::IsUtf8EncodingSupported() const
{
  // Supported from Visual Studio 16.10 Preview 2.
  if (this->Version > cmGlobalVisualStudioGenerator::VSVersion::VS16) {
    return true;
  }
  if (this->Version < cmGlobalVisualStudioGenerator::VSVersion::VS16) {
    return false;
  }
  static std::string const vsVer16_10_P2 = "16.10.31213.239";
  cm::optional<std::string> vsVer = this->GetVSInstanceVersion();
  return (vsVer &&
          cmSystemTools::VersionCompareGreaterEq(*vsVer, vsVer16_10_P2));
}

bool cmGlobalVisualStudioVersionedGenerator::IsScanDependenciesSupported()
  const
{
  // Supported from Visual Studio 17.6 Preview 7.
  if (this->Version > cmGlobalVisualStudioGenerator::VSVersion::VS17) {
    return true;
  }
  if (this->Version < cmGlobalVisualStudioGenerator::VSVersion::VS17) {
    return false;
  }
  static std::string const vsVer17_6_P7 = "17.6.33706.43";
  cm::optional<std::string> vsVer = this->GetVSInstanceVersion();
  return (vsVer &&
          cmSystemTools::VersionCompareGreaterEq(*vsVer, vsVer17_6_P7));
}

char const*
cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision()
  const
{
  switch (this->Version) {
    case cmGlobalVisualStudioGenerator::VSVersion::VS14:
      return "2.0";
    case cmGlobalVisualStudioGenerator::VSVersion::VS15:
    case cmGlobalVisualStudioGenerator::VSVersion::VS16:
    case cmGlobalVisualStudioGenerator::VSVersion::VS17:
    case cmGlobalVisualStudioGenerator::VSVersion::VS18:
      return "3.0";
  }
  return "";
}

cmGlobalVisualStudioVersionedGenerator::AuxToolset
cmGlobalVisualStudioVersionedGenerator::FindAuxToolset(
  std::string& version, std::string& props) const
{
  if (version.empty()) {
    return AuxToolset::None;
  }

  std::string instancePath;
  this->GetVSInstance(instancePath);
  cmSystemTools::ConvertToUnixSlashes(instancePath);

  // Translate three-component format accepted by "vcvarsall -vcvars_ver=".
  cmsys::RegularExpression threeComponentRegex(
    "^([0-9]+\\.[0-9]+)\\.[0-9][0-9][0-9][0-9][0-9]$");
  // The two-component format represents the two major components of the
  // three-component format
  cmsys::RegularExpression twoComponentRegex("^([0-9]+\\.[0-9]+)$");
  if (threeComponentRegex.find(version)) {
    // Load "VC/Auxiliary/Build/*/Microsoft.VCToolsVersion.*.txt" files
    // with two matching components to check their three-component version.
    std::string const& twoComponent = threeComponentRegex.match(1);
    std::string pattern =
      cmStrCat(instancePath, "/VC/Auxiliary/Build/"_s, twoComponent,
               "*/Microsoft.VCToolsVersion."_s, twoComponent, "*.txt"_s);
    cmsys::Glob glob;
    glob.SetRecurseThroughSymlinks(false);
    if (glob.FindFiles(pattern)) {
      for (std::string const& txt : glob.GetFiles()) {
        std::string ver;
        cmsys::ifstream fin(txt.c_str());
        if (fin && std::getline(fin, ver)) {
          // Strip trailing whitespace.
          ver = ver.substr(0, ver.find_first_not_of("0123456789."));
          // If the three-component version matches, translate it to
          // that used by the "Microsoft.VCToolsVersion.*.txt" file name.
          if (ver == version) {
            cmsys::RegularExpression extractVersion(
              "VCToolsVersion\\.([0-9.]+)\\.txt$");
            if (extractVersion.find(txt)) {
              version = extractVersion.match(1);
              break;
            }
          }
        }
      }
    }
  } else if (twoComponentRegex.find(version)) {
    std::string const& twoComponent = twoComponentRegex.match(1);
    std::string pattern =
      cmStrCat(instancePath, "/VC/Auxiliary/Build/"_s, twoComponent,
               "*/Microsoft.VCToolsVersion."_s, twoComponent, "*.txt"_s);
    cmsys::Glob glob;
    glob.SetRecurseThroughSymlinks(false);
    if (glob.FindFiles(pattern) && !glob.GetFiles().empty()) {
      // Since we are only using the first two components of the
      // toolset version, we require a single match.
      if (glob.GetFiles().size() == 1) {
        std::string const& txt = glob.GetFiles()[0];
        std::string ver;
        cmsys::ifstream fin(txt.c_str());
        if (fin && std::getline(fin, ver)) {
          // Strip trailing whitespace.
          ver = ver.substr(0, ver.find_first_not_of("0123456789."));
          // We assume the version is correct, since it is the only one that
          // matched.
          cmsys::RegularExpression extractVersion(
            "VCToolsVersion\\.([0-9.]+)\\.txt$");
          if (extractVersion.find(txt)) {
            version = extractVersion.match(1);
          }
        }
      } else {
        props = cmStrCat(instancePath, "/VC/Auxiliary/Build/"_s);
        return AuxToolset::PropsIndeterminate;
      }
    }
  }

  if (cmSystemTools::VersionCompareGreaterEq(version, "14.20")) {
    props = cmStrCat(instancePath, "/VC/Auxiliary/Build."_s, version,
                     "/Microsoft.VCToolsVersion."_s, version, ".props"_s);
    if (cmSystemTools::PathExists(props)) {
      return AuxToolset::PropsExist;
    }
  }
  props = cmStrCat(instancePath, "/VC/Auxiliary/Build/"_s, version,
                   "/Microsoft.VCToolsVersion."_s, version, ".props"_s);
  if (cmSystemTools::PathExists(props)) {
    return AuxToolset::PropsExist;
  }

  // Accept the toolset version that is default in the current VS version
  // by matching the name later VS versions will use for the SxS props files.
  std::string vcToolsetVersion;
  if (this->vsSetupAPIHelper.GetVCToolsetVersion(vcToolsetVersion)) {
    // Accept an exact-match (three-component version).
    if (version == vcToolsetVersion) {
      return AuxToolset::Default;
    }

    // Accept known SxS props file names using four version components
    // in VS versions later than the current.
    if (version == "14.28.16.9"_s && vcToolsetVersion == "14.28.29910"_s) {
      return AuxToolset::Default;
    }
    if (version == "14.29.16.10"_s && vcToolsetVersion == "14.29.30037"_s) {
      return AuxToolset::Default;
    }
    if (version == "14.29.16.11"_s && vcToolsetVersion == "14.29.30133"_s) {
      return AuxToolset::Default;
    }

    // The first two components of the default toolset version typically
    // match the name used by later VS versions for the SxS props files.
    cmsys::RegularExpression twoComponent("^([0-9]+\\.[0-9]+)");
    if (twoComponent.find(version)) {
      std::string const versionPrefix = cmStrCat(twoComponent.match(1), '.');
      if (cmHasPrefix(vcToolsetVersion, versionPrefix)) {
        return AuxToolset::Default;
      }
    }
  }

  return AuxToolset::PropsMissing;
}

bool cmGlobalVisualStudioVersionedGenerator::SelectWindowsStoreToolset(
  std::string& toolset) const
{
  if (cmHasLiteralPrefix(this->SystemVersion, "10.0")) {
    if (this->IsWindowsStoreToolsetInstalled() &&
        this->IsWindowsDesktopToolsetInstalled()) {
      toolset = VSVersionToToolset(this->Version);
      return true;
    }
    return false;
  }
  return this->cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset(
    toolset);
}

bool cmGlobalVisualStudioVersionedGenerator::IsWindowsDesktopToolsetInstalled()
  const
{
  return vsSetupAPIHelper.IsVSInstalled();
}

bool cmGlobalVisualStudioVersionedGenerator::IsWindowsStoreToolsetInstalled()
  const
{
  return vsSetupAPIHelper.IsWin10SDKInstalled();
}

bool cmGlobalVisualStudioVersionedGenerator::IsWin81SDKInstalled() const
{
  // Does the VS installer tool know about one?
  if (vsSetupAPIHelper.IsWin81SDKInstalled()) {
    return true;
  }

  // Does the registry know about one (e.g. from VS 2015)?
  std::string win81Root;
  if (cmSystemTools::ReadRegistryValue(
        "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
        "Windows Kits\\Installed Roots;KitsRoot81",
        win81Root, cmSystemTools::KeyWOW64_32) ||
      cmSystemTools::ReadRegistryValue(
        "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\"
        "Windows Kits\\Installed Roots;KitsRoot81",
        win81Root, cmSystemTools::KeyWOW64_32)) {
    return cmSystemTools::FileExists(
      cmStrCat(win81Root, "/include/um/windows.h"), true);
  }
  return false;
}

std::string
cmGlobalVisualStudioVersionedGenerator::GetWindows10SDKMaxVersionDefault(
  cmMakefile*) const
{
  return std::string();
}

cm::optional<std::string>
cmGlobalVisualStudioVersionedGenerator::FindMSBuildCommandEarly(cmMakefile* mf)
{
  std::string instance = mf->GetSafeDefinition("CMAKE_GENERATOR_INSTANCE");
  if (!this->SetGeneratorInstance(instance, mf)) {
    cmSystemTools::SetFatalErrorOccurred();
    return {};
  }
  return this->cmGlobalVisualStudio14Generator::FindMSBuildCommandEarly(mf);
}

std::string cmGlobalVisualStudioVersionedGenerator::FindMSBuildCommand()
{
  std::string msbuild;

  // Ask Visual Studio Installer tool.
  std::string vs;
  if (vsSetupAPIHelper.GetVSInstanceInfo(vs)) {
    if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS17) {
      if (VSIsArm64Host()) {
        if (VSHasDotNETFrameworkArm64()) {
          msbuild = cmStrCat(vs, "/MSBuild/Current/Bin/arm64/MSBuild.exe");
          if (cmSystemTools::FileExists(msbuild)) {
            return msbuild;
          }
        }
        if (VSIsWindows11OrGreater()) {
          msbuild = cmStrCat(vs, "/MSBuild/Current/Bin/amd64/MSBuild.exe");
          if (cmSystemTools::FileExists(msbuild)) {
            return msbuild;
          }
        }
      } else {
        msbuild = cmStrCat(vs, "/MSBuild/Current/Bin/amd64/MSBuild.exe");
        if (cmSystemTools::FileExists(msbuild)) {
          return msbuild;
        }
      }
    }
    msbuild = cmStrCat(vs, "/MSBuild/Current/Bin/MSBuild.exe");
    if (cmSystemTools::FileExists(msbuild)) {
      return msbuild;
    }
    msbuild = cmStrCat(vs, "/MSBuild/15.0/Bin/MSBuild.exe");
    if (cmSystemTools::FileExists(msbuild)) {
      return msbuild;
    }
  }

  msbuild = "MSBuild.exe";
  return msbuild;
}

std::string cmGlobalVisualStudioVersionedGenerator::FindDevEnvCommand()
{
  std::string devenv;

  // Ask Visual Studio Installer tool.
  std::string vs;
  if (vsSetupAPIHelper.GetVSInstanceInfo(vs)) {
    devenv = cmStrCat(vs, "/Common7/IDE/devenv.com");
    if (cmSystemTools::FileExists(devenv)) {
      return devenv;
    }
  }

  devenv = "devenv.com";
  return devenv;
}
