/* 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 "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.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 0;
  }
  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:
  cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
                                           cmake* cm) const override
  {
    std::string genName;
    const char* p = cmVS14GenName(name, genName);
    if (!p) {
      return 0;
    }
    if (!*p) {
      return new cmGlobalVisualStudio14Generator(cm, genName, "");
    }
    if (*p++ != ' ') {
      return 0;
    }
    if (strcmp(p, "Win64") == 0) {
      return new cmGlobalVisualStudio14Generator(cm, genName, "x64");
    }
    if (strcmp(p, "ARM") == 0) {
      return new cmGlobalVisualStudio14Generator(cm, genName, "ARM");
    }
    return 0;
  }

  void GetDocumentation(cmDocumentationEntry& entry) const override
  {
    entry.Name = std::string(vs14generatorName) + " [arch]";
    entry.Brief = "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.push_back(vs14generatorName + std::string(" ARM"));
    names.push_back(vs14generatorName + 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");
    return platforms;
  }

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

cmGlobalGeneratorFactory* cmGlobalVisualStudio14Generator::NewFactory()
{
  return 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->DefaultCLFlagTableName = "v140";
  this->DefaultCSharpFlagTableName = "v140";
  this->DefaultLibFlagTableName = "v14";
  this->DefaultLinkFlagTableName = "v140";
  this->DefaultMasmFlagTableName = "v14";
  this->DefaultRCFlagTableName = "v14";
  this->Version = VS14;
}

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

bool cmGlobalVisualStudio14Generator::InitializeWindows(cmMakefile* mf)
{
  if (cmHasLiteralPrefix(this->SystemVersion, "10.0")) {
    return this->SelectWindows10SDK(mf, false);
  }
  return true;
}

bool cmGlobalVisualStudio14Generator::InitializeWindowsStore(cmMakefile* mf)
{
  std::ostringstream e;
  if (!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset)) {
    if (this->DefaultPlatformToolset.empty()) {
      e << this->GetName()
        << " supports Windows Store '8.0', '8.1' and "
           "'10.0', but not '"
        << this->SystemVersion << "'.  Check CMAKE_SYSTEM_VERSION.";
    } else {
      e << "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.str());
    return false;
  }
  if (cmHasLiteralPrefix(this->SystemVersion, "10.0")) {
    return this->SelectWindows10SDK(mf, true);
  }
  return true;
}

bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf,
                                                         bool required)
{
  // Find the default version of the Windows 10 SDK.
  std::string const version = this->GetWindows10SDKVersion();
  if (required && version.empty()) {
    std::ostringstream e;
    e << "Could not find an appropriate version of the Windows 10 SDK"
      << " installed on this machine";
    mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
    return false;
  }
  this->SetWindowsTargetPlatformVersion(version, mf);
  return true;
}

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

bool cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset(
  std::string& toolset) const
{
  if (cmHasLiteralPrefix(this->SystemVersion, "10.0")) {
    if (this->IsWindowsStoreToolsetInstalled() &&
        this->IsWindowsDesktopToolsetInstalled()) {
      toolset = "v140";
      return true;
    } else {
      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);
}

std::string cmGlobalVisualStudio14Generator::GetWindows10SDKMaxVersion() 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(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()
{
#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 = 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.
  cmEraseIf(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.
  std::string maxVersion = this->GetWindows10SDKMaxVersion();
  if (!maxVersion.empty()) {
    cmEraseIf(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 target 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
  // Return an empty string
  return std::string();
}
