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

#include <cmext/string_view>

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

#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmVSSetupHelper.h"
#include "cmake.h"

#if defined(_M_ARM64)
#  define HOST_PLATFORM_NAME "ARM64"
#  define HOST_TOOLS_ARCH ""
#elif defined(_M_ARM)
#  define HOST_PLATFORM_NAME "ARM"
#  define HOST_TOOLS_ARCH ""
#elif defined(_M_IA64)
#  define HOST_PLATFORM_NAME "Itanium"
#  define HOST_TOOLS_ARCH ""
#elif defined(_WIN64)
#  define HOST_PLATFORM_NAME "x64"
#  define HOST_TOOLS_ARCH "x64"
#else
static bool VSIsWow64()
{
  BOOL isWow64 = false;
  return IsWow64Process(GetCurrentProcess(), &isWow64) && isWow64;
}
#endif

static std::string VSHostPlatformName()
{
#ifdef HOST_PLATFORM_NAME
  return HOST_PLATFORM_NAME;
#else
  if (VSIsWow64()) {
    return "x64";
  } else {
    return "Win32";
  }
#endif
}

static std::string VSHostArchitecture()
{
#ifdef HOST_TOOLS_ARCH
  return HOST_TOOLS_ARCH;
#else
  if (VSIsWow64()) {
    return "x64";
  } else {
    return "x86";
  }
#endif
}

static unsigned int VSVersionToMajor(
  cmGlobalVisualStudioGenerator::VSVersion v)
{
  switch (v) {
    case cmGlobalVisualStudioGenerator::VS9:
      return 9;
    case cmGlobalVisualStudioGenerator::VS10:
      return 10;
    case cmGlobalVisualStudioGenerator::VS11:
      return 11;
    case cmGlobalVisualStudioGenerator::VS12:
      return 12;
    case cmGlobalVisualStudioGenerator::VS14:
      return 14;
    case cmGlobalVisualStudioGenerator::VS15:
      return 15;
    case cmGlobalVisualStudioGenerator::VS16:
      return 16;
  }
  return 0;
}

static const char* VSVersionToToolset(
  cmGlobalVisualStudioGenerator::VSVersion v)
{
  switch (v) {
    case cmGlobalVisualStudioGenerator::VS9:
      return "v90";
    case cmGlobalVisualStudioGenerator::VS10:
      return "v100";
    case cmGlobalVisualStudioGenerator::VS11:
      return "v110";
    case cmGlobalVisualStudioGenerator::VS12:
      return "v120";
    case cmGlobalVisualStudioGenerator::VS14:
      return "v140";
    case cmGlobalVisualStudioGenerator::VS15:
      return "v141";
    case cmGlobalVisualStudioGenerator::VS16:
      return "v142";
  }
  return "";
}

static const char* VSVersionToAndroidToolset(
  cmGlobalVisualStudioGenerator::VSVersion v)
{
  switch (v) {
    case cmGlobalVisualStudioGenerator::VS9:
    case cmGlobalVisualStudioGenerator::VS10:
    case cmGlobalVisualStudioGenerator::VS11:
    case cmGlobalVisualStudioGenerator::VS12:
      return "";
    case cmGlobalVisualStudioGenerator::VS14:
      return "Clang_3_8";
    case cmGlobalVisualStudioGenerator::VS15:
    case cmGlobalVisualStudioGenerator::VS16:
      return "Clang_5_0";
  }
  return "";
}

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

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

class cmGlobalVisualStudioVersionedGenerator::Factory15
  : public cmGlobalGeneratorFactory
{
public:
  std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
    const std::string& name, bool allowArch, cmake* cm) const override
  {
    std::string genName;
    const char* p = cmVS15GenName(name, genName);
    if (!p) {
      return std::unique_ptr<cmGlobalGenerator>();
    }
    if (!*p) {
      return std::unique_ptr<cmGlobalGenerator>(
        new cmGlobalVisualStudioVersionedGenerator(
          cmGlobalVisualStudioGenerator::VS15, cm, genName, ""));
    }
    if (!allowArch || *p++ != ' ') {
      return std::unique_ptr<cmGlobalGenerator>();
    }
    if (strcmp(p, "Win64") == 0) {
      return std::unique_ptr<cmGlobalGenerator>(
        new cmGlobalVisualStudioVersionedGenerator(
          cmGlobalVisualStudioGenerator::VS15, cm, genName, "x64"));
    }
    if (strcmp(p, "ARM") == 0) {
      return std::unique_ptr<cmGlobalGenerator>(
        new cmGlobalVisualStudioVersionedGenerator(
          cmGlobalVisualStudioGenerator::VS15, cm, genName, "ARM"));
    }
    return std::unique_ptr<cmGlobalGenerator>();
  }

  void GetDocumentation(cmDocumentationEntry& entry) const override
  {
    entry.Name = std::string(vs15generatorName) + " [arch]";
    entry.Brief = "Generates Visual Studio 2017 project files.  "
                  "Optional [arch] can be \"Win64\" or \"ARM\".";
  }

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

  std::vector<std::string> GetGeneratorNamesWithPlatform() const override
  {
    std::vector<std::string> names;
    names.push_back(vs15generatorName + std::string(" ARM"));
    names.push_back(vs15generatorName + std::string(" Win64"));
    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 "Win32"; }
};

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

static const char vs16generatorName[] = "Visual Studio 16 2019";

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

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

  void GetDocumentation(cmDocumentationEntry& entry) const override
  {
    entry.Name = std::string(vs16generatorName);
    entry.Brief = "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;
  }

  std::vector<std::string> GetGeneratorNamesWithPlatform() const override
  {
    return std::vector<std::string>();
  }

  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 VSHostPlatformName();
  }
};

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

cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator(
  VSVersion version, cmake* cm, const std::string& name,
  std::string const& platformInGeneratorName)
  : cmGlobalVisualStudio14Generator(cm, name, platformInGeneratorName)
  , 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::VS16) {
    this->DefaultPlatformName = VSHostPlatformName();
    this->DefaultPlatformToolsetHostArchitecture = VSHostArchitecture();
  }
}

bool cmGlobalVisualStudioVersionedGenerator::MatchesGeneratorName(
  const std::string& name) const
{
  std::string genName;
  switch (this->Version) {
    case cmGlobalVisualStudioGenerator::VS9:
    case cmGlobalVisualStudioGenerator::VS10:
    case cmGlobalVisualStudioGenerator::VS11:
    case cmGlobalVisualStudioGenerator::VS12:
    case cmGlobalVisualStudioGenerator::VS14:
      break;
    case cmGlobalVisualStudioGenerator::VS15:
      if (cmVS15GenName(name, genName)) {
        return genName == this->GetName();
      }
      break;
    case cmGlobalVisualStudioGenerator::VS16:
      if (cmVS16GenName(name, genName)) {
        return genName == this->GetName();
      }
      break;
  }
  return false;
}

bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
  std::string const& i, cmMakefile* mf)
{
  if (!i.empty()) {
    if (!this->vsSetupAPIHelper.SetVSInstance(i)) {
      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 */
      mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
      return false;
    }
  }

  std::string vsInstance;
  if (!this->vsSetupAPIHelper.GetVSInstanceInfo(vsInstance)) {
    std::ostringstream e;
    /* clang-format off */
    e <<
      "Generator\n"
      "  " << this->GetName() << "\n"
      "could not find any instance of Visual Studio.\n";
    /* clang-format on */
    mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
    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.c_str(),
      "Generator instance identifier.", cmStateEnums::INTERNAL);
  }

  return true;
}

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

bool cmGlobalVisualStudioVersionedGenerator::GetVSInstanceVersion(
  unsigned long long& vsInstanceVersion) const
{
  return vsSetupAPIHelper.GetVSInstanceVersion(vsInstanceVersion);
}

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;
  }
  unsigned long long const vsInstanceVersion16_7_P2 = 4503631666610212;
  unsigned long long vsInstanceVersion;
  return (this->GetVSInstanceVersion(vsInstanceVersion) &&
          vsInstanceVersion > vsInstanceVersion16_7_P2);
}

const char*
cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision()
  const
{
  switch (this->Version) {
    case cmGlobalVisualStudioGenerator::VS9:
    case cmGlobalVisualStudioGenerator::VS10:
    case cmGlobalVisualStudioGenerator::VS11:
    case cmGlobalVisualStudioGenerator::VS12:
      return "";
    case cmGlobalVisualStudioGenerator::VS14:
      return "2.0";
    case cmGlobalVisualStudioGenerator::VS15:
    case cmGlobalVisualStudioGenerator::VS16:
      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 threeComponent(
    "^([0-9]+\\.[0-9]+)\\.[0-9][0-9][0-9][0-9][0-9]$");
  if (threeComponent.find(version)) {
    // Load "VC/Auxiliary/Build/*/Microsoft.VCToolsVersion.*.txt" files
    // with two matching components to check their three-component version.
    std::string const& twoComponent = threeComponent.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;
            }
          }
        }
      }
    }
  }

  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" && vcToolsetVersion == "14.28.29910") {
      return AuxToolset::Default;
    }
    if (version == "14.29.16.10" && vcToolsetVersion == "14.29.30037") {
      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::InitializeWindows(cmMakefile* mf)
{
  // If the Win 8.1 SDK is installed then we can select a SDK matching
  // the target Windows version.
  if (this->IsWin81SDKInstalled()) {
    // VS 2019 does not default to 8.1 so specify it explicitly when needed.
    if (this->Version >= cmGlobalVisualStudioGenerator::VS16 &&
        !cmSystemTools::VersionCompareGreater(this->SystemVersion, "8.1")) {
      this->SetWindowsTargetPlatformVersion("8.1", mf);
      return true;
    }
    return cmGlobalVisualStudio14Generator::InitializeWindows(mf);
  }
  // Otherwise we must choose a Win 10 SDK even if we are not targeting
  // Windows 10.
  return this->SelectWindows10SDK(mf, false);
}

bool cmGlobalVisualStudioVersionedGenerator::SelectWindowsStoreToolset(
  std::string& toolset) const
{
  if (cmHasLiteralPrefix(this->SystemVersion, "10.0")) {
    if (this->IsWindowsStoreToolsetInstalled() &&
        this->IsWindowsDesktopToolsetInstalled()) {
      toolset = VSVersionToToolset(this->Version);
      return true;
    } else {
      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(win81Root + "/include/um/windows.h",
                                     true);
  }
  return false;
}

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

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

  // Ask Visual Studio Installer tool.
  std::string vs;
  if (vsSetupAPIHelper.GetVSInstanceInfo(vs)) {
    msbuild = vs + "/MSBuild/Current/Bin/MSBuild.exe";
    if (cmSystemTools::FileExists(msbuild)) {
      return msbuild;
    }
    msbuild = 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 = vs + "/Common7/IDE/devenv.com";
    if (cmSystemTools::FileExists(devenv)) {
      return devenv;
    }
  }

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