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

#include <cstring>
#include <sstream>

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

#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalVisualStudioGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"

static const char vs14generatorName[] = "Visual Studio 14 2015";

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

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

  cmDocumentationEntry GetDocumentation() const override
  {
    return { cmStrCat(vs14generatorName, " [arch]"),
             "Generates Visual Studio 2015 project files.  "
             "Optional [arch] can be \"Win64\" or \"ARM\"." };
  }

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

  std::vector<std::string> GetGeneratorNamesWithPlatform() const override
  {
    std::vector<std::string> names;
    names.emplace_back(cmStrCat(vs14generatorName, " ARM"));
    names.emplace_back(cmStrCat(vs14generatorName, " 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");
    return platforms;
  }

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

std::unique_ptr<cmGlobalGeneratorFactory>
cmGlobalVisualStudio14Generator::NewFactory()
{
  return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}

cmGlobalVisualStudio14Generator::cmGlobalVisualStudio14Generator(
  cmake* cm, const std::string& name,
  std::string const& platformInGeneratorName)
  : cmGlobalVisualStudio12Generator(cm, name, platformInGeneratorName)
{
  std::string vc14Express;
  this->ExpressEdition = cmSystemTools::ReadRegistryValue(
    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\14.0\\Setup\\VC;"
    "ProductDir",
    vc14Express, cmSystemTools::KeyWOW64_32);
  this->DefaultPlatformToolset = "v140";
  this->DefaultAndroidToolset = "Clang_3_8";
  this->DefaultCLFlagTableName = "v140";
  this->DefaultCSharpFlagTableName = "v140";
  this->DefaultLibFlagTableName = "v14";
  this->DefaultLinkFlagTableName = "v140";
  this->DefaultMasmFlagTableName = "v14";
  this->DefaultRCFlagTableName = "v14";
  this->Version = VSVersion::VS14;
}

bool cmGlobalVisualStudio14Generator::MatchesGeneratorName(
  const std::string& name) const
{
  std::string genName;
  if (cmVS14GenName(name, genName)) {
    return genName == this->GetName();
  }
  return false;
}

bool cmGlobalVisualStudio14Generator::InitializePlatformWindows(cmMakefile* mf)
{
  // If a Windows SDK version is explicitly requested, search for it.
  if (this->GeneratorPlatformVersion) {
    std::string const& version = *this->GeneratorPlatformVersion;

    // VS 2019 and above support specifying plain "10.0".
    if (version == "10.0"_s) {
      if (this->Version >= VSVersion::VS16) {
        this->SetWindowsTargetPlatformVersion("10.0", mf);
        return true;
      }
      /* clang-format off */
      mf->IssueMessage(MessageType::FATAL_ERROR, cmStrCat(
          "Generator\n"
          "  ", this->GetName(), "\n"
          "given platform specification containing a\n"
          "  version=10.0\n"
          "field.  The value 10.0 is only supported by VS 2019 and above.\n"
          ));
      /* clang-format on */
      return false;
    }

    if (cmHasLiteralPrefix(version, "10.0.")) {
      return this->SelectWindows10SDK(mf);
    }

    if (version == "8.1"_s) {
      if (this->IsWin81SDKInstalled()) {
        this->SetWindowsTargetPlatformVersion("8.1", mf);
        return true;
      }
      /* clang-format off */
      mf->IssueMessage(MessageType::FATAL_ERROR, cmStrCat(
          "Generator\n"
          "  ", this->GetName(), "\n"
          "given platform specification containing a\n"
          "  version=8.1\n"
          "field, but the Windows 8.1 SDK is not installed.\n"
          ));
      /* clang-format on */
      return false;
    }

    if (version.empty()) {
      /* clang-format off */
      mf->IssueMessage(MessageType::FATAL_ERROR, cmStrCat(
          "Generator\n"
          "  ", this->GetName(), "\n"
          "given platform specification with empty\n"
          "  version=\n"
          "field.\n"
          ));
      /* clang-format on */
      return false;
    }

    /* clang-format off */
    mf->IssueMessage(MessageType::FATAL_ERROR, cmStrCat(
        "Generator\n"
        "  ", this->GetName(), "\n"
        "given platform specification containing a\n"
        "  version=", version, "\n"
        "field with unsupported value.\n"
        ));
    /* clang-format on */
    return false;
  }

  // If we are targeting Windows 10+, we select a Windows 10 SDK.
  // If no Windows 8.1 SDK is installed, which is possible with VS 2017 and
  // higher, then we must choose a Windows 10 SDK anyway.
  if (cmHasLiteralPrefix(this->SystemVersion, "10.0") ||
      !this->IsWin81SDKInstalled()) {
    return this->SelectWindows10SDK(mf);
  }

  // Under CMP0149 NEW behavior, we search for a Windows 10 SDK even
  // when targeting older Windows versions, but it is not required.
  if (mf->GetPolicyStatus(cmPolicies::CMP0149) == cmPolicies::NEW) {
    std::string const version = this->GetWindows10SDKVersion(mf);
    if (!version.empty()) {
      this->SetWindowsTargetPlatformVersion(version, mf);
      return true;
    }
  }

  // We are not targeting Windows 10+, so fall back to the Windows 8.1 SDK.
  // For VS 2019 and above we must explicitly specify it.
  if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16 &&
      !cmSystemTools::VersionCompareGreater(this->SystemVersion, "8.1")) {
    this->SetWindowsTargetPlatformVersion("8.1", mf);
  }
  return true;
}

bool cmGlobalVisualStudio14Generator::VerifyNoGeneratorPlatformVersion(
  cmMakefile* mf) const
{
  if (!this->GeneratorPlatformVersion) {
    return true;
  }
  std::ostringstream e;
  /* clang-format off */
  e <<
    "Generator\n"
    "  " << this->GetName() << "\n"
    "given platform specification containing a\n"
    "  version=" << *this->GeneratorPlatformVersion << "\n"
    "field.  The version field is not supported when targeting\n"
    "  " << this->SystemName << ' ' << this->SystemVersion << '\n'
    ;
  /* clang-format on */
  mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
  return false;
}

bool cmGlobalVisualStudio14Generator::InitializeWindowsStore(cmMakefile* mf)
{
  if (!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset)) {
    std::string e;
    if (this->DefaultPlatformToolset.empty()) {
      e = cmStrCat(this->GetName(),
                   " supports Windows Store '8.0', '8.1' and "
                   "'10.0', but not '",
                   this->SystemVersion, "'.  Check CMAKE_SYSTEM_VERSION.");
    } else {
      e = cmStrCat(
        "A Windows Store component with CMake requires both the Windows "
        "Desktop SDK as well as the Windows Store '",
        this->SystemVersion,
        "' SDK. Please make sure that you have both installed");
    }
    mf->IssueMessage(MessageType::FATAL_ERROR, e);
    return false;
  }
  return true;
}

bool cmGlobalVisualStudio14Generator::InitializeAndroid(cmMakefile*)
{
  return true;
}

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

bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf)
{
  // Find the default version of the Windows 10 SDK.
  std::string const version = this->GetWindows10SDKVersion(mf);

  if (version.empty()) {
    if (this->GeneratorPlatformVersion) {
      mf->IssueMessage(
        MessageType::FATAL_ERROR,
        cmStrCat("Generator\n  ", this->GetName(),
                 "\ngiven platform specification with\n  version=",
                 *this->GeneratorPlatformVersion,
                 "\nfield, but no Windows SDK with that version was found."));
      return false;
    }

    if (this->SystemName == "WindowsStore"_s) {
      mf->IssueMessage(
        MessageType::FATAL_ERROR,
        "Could not find an appropriate version of the Windows 10 SDK"
        " installed on this machine");
      return false;
    }
  }

  this->SetWindowsTargetPlatformVersion(version, mf);
  return true;
}

void cmGlobalVisualStudio14Generator::SetWindowsTargetPlatformVersion(
  std::string const& version, cmMakefile* mf)
{
  this->WindowsTargetPlatformVersion = version;
  if (!this->WindowsTargetPlatformVersion.empty() &&
      !cmSystemTools::VersionCompareEqual(this->WindowsTargetPlatformVersion,
                                          this->SystemVersion)) {
    mf->DisplayStatus(cmStrCat("Selecting Windows SDK version ",
                               this->WindowsTargetPlatformVersion,
                               " to target Windows ", this->SystemVersion,
                               '.'),
                      -1);
  }
  mf->AddDefinition("CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION",
                    this->WindowsTargetPlatformVersion);
}

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

bool cmGlobalVisualStudio14Generator::IsWindowsDesktopToolsetInstalled() const
{
  const char desktop10Key[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
                              "VisualStudio\\14.0\\VC\\Runtimes";

  std::vector<std::string> vc14;
  return cmSystemTools::GetRegistrySubKeys(desktop10Key, vc14,
                                           cmSystemTools::KeyWOW64_32);
}

bool cmGlobalVisualStudio14Generator::IsWindowsStoreToolsetInstalled() const
{
  const char universal10Key[] =
    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
    "VisualStudio\\14.0\\Setup\\Build Tools for Windows 10;SrcPath";

  std::string win10SDK;
  return cmSystemTools::ReadRegistryValue(universal10Key, win10SDK,
                                          cmSystemTools::KeyWOW64_32);
}

bool cmGlobalVisualStudio14Generator::IsWin81SDKInstalled() const
{
  return true;
}

std::string cmGlobalVisualStudio14Generator::GetWindows10SDKMaxVersion(
  cmMakefile* mf) const
{
  // if the given value is set, it can either be OFF/FALSE or a valid SDK
  // string
  if (cmValue value = mf->GetDefinition(
        "CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM")) {

    // If the value is some off/false value, then there is NO maximum set.
    if (cmIsOff(value)) {
      return std::string();
    }
    // If the value is something else, trust that it is a valid SDK value.
    if (value) {
      return *value;
    }
    // If value is an invalid pointer, leave result unchanged.
  }

  return this->GetWindows10SDKMaxVersionDefault(mf);
}

std::string cmGlobalVisualStudio14Generator::GetWindows10SDKMaxVersionDefault(
  cmMakefile*) const
{
  // The last Windows 10 SDK version that VS 2015 can target is 10.0.14393.0.
  //
  // "VS 2015 Users: The Windows 10 SDK (15063, 16299, 17134, 17763) is
  // officially only supported for VS 2017." From:
  // https://blogs.msdn.microsoft.com/chuckw/2018/10/02/windows-10-october-2018-update/
  return "10.0.14393.0";
}

#if defined(_WIN32) && !defined(__CYGWIN__)
struct NoWindowsH
{
  bool operator()(std::string const& p)
  {
    return !cmSystemTools::FileExists(cmStrCat(p, "/um/windows.h"), true);
  }
};
class WindowsSDKTooRecent
{
  std::string const& MaxVersion;

public:
  WindowsSDKTooRecent(std::string const& maxVersion)
    : MaxVersion(maxVersion)
  {
  }
  bool operator()(std::string const& v)
  {
    return cmSystemTools::VersionCompareGreater(v, MaxVersion);
  }
};
#endif

std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion(
  cmMakefile* mf)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
  std::vector<std::string> win10Roots;

  {
    std::string win10Root;
    if (cmSystemTools::GetEnv("CMAKE_WINDOWS_KITS_10_DIR", win10Root)) {
      cmSystemTools::ConvertToUnixSlashes(win10Root);
      win10Roots.push_back(win10Root);
    }
  }

  {
    // This logic is taken from the vcvarsqueryregistry.bat file from VS2015
    // Try HKLM and then HKCU.
    std::string win10Root;
    if (cmSystemTools::ReadRegistryValue(
          "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
          "Windows Kits\\Installed Roots;KitsRoot10",
          win10Root, cmSystemTools::KeyWOW64_32) ||
        cmSystemTools::ReadRegistryValue(
          "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\"
          "Windows Kits\\Installed Roots;KitsRoot10",
          win10Root, cmSystemTools::KeyWOW64_32)) {
      cmSystemTools::ConvertToUnixSlashes(win10Root);
      win10Roots.push_back(win10Root);
    }
  }

  if (win10Roots.empty()) {
    return std::string();
  }

  std::vector<std::string> sdks;
  // Grab the paths of the different SDKs that are installed
  for (std::string const& i : win10Roots) {
    std::string path = cmStrCat(i, "/Include/*");
    cmSystemTools::GlobDirs(path, sdks);
  }

  // Skip SDKs that do not contain <um/windows.h> because that indicates that
  // only the UCRT MSIs were installed for them.
  cm::erase_if(sdks, NoWindowsH());

  // Only use the filename, which will be the SDK version.
  for (std::string& i : sdks) {
    i = cmSystemTools::GetFilenameName(i);
  }

  // Skip SDKs that cannot be used with our toolset, unless the user does not
  // want to limit the highest supported SDK according to the Microsoft
  // documentation.
  std::string maxVersion = this->GetWindows10SDKMaxVersion(mf);
  if (!maxVersion.empty()) {
    cm::erase_if(sdks, WindowsSDKTooRecent(maxVersion));
  }

  // Sort the results to make sure we select the most recent one.
  std::sort(sdks.begin(), sdks.end(), cmSystemTools::VersionCompareGreater);

  // Look for a SDK exactly matching the requested version, if any.
  if (this->GeneratorPlatformVersion) {
    for (std::string const& i : sdks) {
      if (cmSystemTools::VersionCompareEqual(
            i, *this->GeneratorPlatformVersion)) {
        return i;
      }
    }
    // An exact version was requested but not found.
    // Our caller will issue the error message.
    return std::string();
  }

  if (mf->GetPolicyStatus(cmPolicies::CMP0149) == cmPolicies::NEW) {
    if (cm::optional<std::string> const envVer =
          cmSystemTools::GetEnvVar("WindowsSDKVersion")) {
      // Look for a SDK exactly matching the environment variable.
      for (std::string const& i : sdks) {
        if (cmSystemTools::VersionCompareEqual(i, *envVer)) {
          return i;
        }
      }
    }
  } else {
    // Look for a SDK exactly matching the target Windows version.
    for (std::string const& i : sdks) {
      if (cmSystemTools::VersionCompareEqual(i, this->SystemVersion)) {
        return i;
      }
    }
  }

  if (!sdks.empty()) {
    // Use the latest Windows 10 SDK since the exact version is not available.
    return sdks.at(0);
  }
#endif
  (void)mf;
  // Return an empty string
  return std::string();
}
