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

#include <utility>

#if !defined(CMAKE_BOOTSTRAP)
#  include <cm3p/json/reader.h>
#  include <cm3p/json/value.h>
#endif

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

#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

#ifndef VSSetupConstants
#  define VSSetupConstants
/* clang-format off */
const IID IID_ISetupConfiguration = {
  0x42843719, 0xDB4C, 0x46C2,
  { 0x8E, 0x7C, 0x64, 0xF1, 0x81, 0x6E, 0xFD, 0x5B }
};
const IID IID_ISetupConfiguration2 = {
  0x26AAB78C, 0x4A60, 0x49D6,
  { 0xAF, 0x3B, 0x3C, 0x35, 0xBC, 0x93, 0x36, 0x5D }
};
const IID IID_ISetupPackageReference = {
  0xda8d8a16, 0xb2b6, 0x4487,
  { 0xa2, 0xf1, 0x59, 0x4c, 0xcc, 0xcd, 0x6b, 0xf5 }
};
const IID IID_ISetupHelper = {
  0x42b21b78, 0x6192, 0x463e,
  { 0x87, 0xbf, 0xd5, 0x77, 0x83, 0x8f, 0x1d, 0x5c }
};
const IID IID_IEnumSetupInstances = {
  0x6380BCFF, 0x41D3, 0x4B2E,
  { 0x8B, 0x2E, 0xBF, 0x8A, 0x68, 0x10, 0xC8, 0x48 }
};
const IID IID_ISetupInstance2 = {
  0x89143C9A, 0x05AF, 0x49B0,
  { 0xB7, 0x17, 0x72, 0xE2, 0x18, 0xA2, 0x18, 0x5C }
};
const IID IID_ISetupInstance = {
  0xB41463C3, 0x8866, 0x43B5,
  { 0xBC, 0x33, 0x2B, 0x06, 0x76, 0xF7, 0xF4, 0x2E }
};
const CLSID CLSID_SetupConfiguration = {
  0x177F0C4A, 0x1CD3, 0x4DE7,
  { 0xA3, 0x2C, 0x71, 0xDB, 0xBB, 0x9F, 0xA3, 0x6D }
};
/* clang-format on */
#endif

namespace {
const WCHAR* Win10SDKComponent =
  L"Microsoft.VisualStudio.Component.Windows10SDK";
const WCHAR* Win81SDKComponent =
  L"Microsoft.VisualStudio.Component.Windows81SDK";
const WCHAR* ComponentType = L"Component";

bool LoadVSInstanceVCToolsetVersion(VSInstanceInfo& vsInstanceInfo)
{
  std::string const vcRoot = vsInstanceInfo.GetInstallLocation();
  std::string vcToolsVersionFile = cmStrCat(
    vcRoot, "/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt");
  std::string vcToolsVersion;
  cmsys::ifstream fin(vcToolsVersionFile.c_str());
  if (!fin || !cmSystemTools::GetLineFromStream(fin, vcToolsVersion)) {
    return false;
  }
  vcToolsVersion = cmTrimWhitespace(vcToolsVersion);
  std::string const vcToolsDir =
    cmStrCat(vcRoot, "/VC/Tools/MSVC/", vcToolsVersion);
  if (!cmSystemTools::FileIsDirectory(vcToolsDir)) {
    return false;
  }
  vsInstanceInfo.VCToolsetVersion = vcToolsVersion;
  return true;
}
}

std::string VSInstanceInfo::GetInstallLocation() const
{
  return this->VSInstallLocation;
}

cmVSSetupAPIHelper::cmVSSetupAPIHelper(unsigned int version)
  : Version(version)
  , setupConfig(nullptr)
  , setupConfig2(nullptr)
  , setupHelper(nullptr)
{
  comInitialized = CoInitializeEx(nullptr, 0);
  if (SUCCEEDED(comInitialized)) {
    Initialize();
  } else {
    initializationFailure = true;
  }
}

cmVSSetupAPIHelper::~cmVSSetupAPIHelper()
{
  setupHelper = nullptr;
  setupConfig2 = nullptr;
  setupConfig = nullptr;
  if (SUCCEEDED(comInitialized)) {
    CoUninitialize();
  }
}

bool cmVSSetupAPIHelper::SetVSInstance(std::string const& vsInstallLocation,
                                       std::string const& vsInstallVersion)
{
  this->SpecifiedVSInstallLocation = vsInstallLocation;
  cmSystemTools::ConvertToUnixSlashes(this->SpecifiedVSInstallLocation);
  this->SpecifiedVSInstallVersion = vsInstallVersion;
  chosenInstanceInfo = VSInstanceInfo();
  return this->EnumerateAndChooseVSInstance();
}

bool cmVSSetupAPIHelper::IsVSInstalled()
{
  return this->EnumerateAndChooseVSInstance();
}

bool cmVSSetupAPIHelper::IsWin10SDKInstalled()
{
  return (this->EnumerateAndChooseVSInstance() &&
          chosenInstanceInfo.IsWin10SDKInstalled);
}

bool cmVSSetupAPIHelper::IsWin81SDKInstalled()
{
  return (this->EnumerateAndChooseVSInstance() &&
          chosenInstanceInfo.IsWin81SDKInstalled);
}

bool cmVSSetupAPIHelper::CheckInstalledComponent(
  SmartCOMPtr<ISetupPackageReference> package, bool& bWin10SDK,
  bool& bWin81SDK)
{
  bool ret = false;
  bWin10SDK = bWin81SDK = false;
  SmartBSTR bstrId;
  if (FAILED(package->GetId(&bstrId))) {
    return ret;
  }

  SmartBSTR bstrType;
  if (FAILED(package->GetType(&bstrType))) {
    return ret;
  }

  std::wstring id = std::wstring(bstrId);
  std::wstring type = std::wstring(bstrType);

  // Checks for any version of Win10 SDK. The version is appended at the end of
  // the
  // component name ex: Microsoft.VisualStudio.Component.Windows10SDK.10240
  if (id.find(Win10SDKComponent) != std::wstring::npos &&
      type == ComponentType) {
    bWin10SDK = true;
    ret = true;
  }

  if (id == Win81SDKComponent && type == ComponentType) {
    bWin81SDK = true;
    ret = true;
  }

  return ret;
}

// Gather additional info such as if VCToolset, WinSDKs are installed, location
// of VS and version information.
bool cmVSSetupAPIHelper::GetVSInstanceInfo(
  SmartCOMPtr<ISetupInstance2> pInstance, VSInstanceInfo& vsInstanceInfo)
{
  if (pInstance == nullptr) {
    return false;
  }

  InstanceState state;
  if (FAILED(pInstance->GetState(&state))) {
    return false;
  }

  SmartBSTR bstrVersion;
  if (FAILED(pInstance->GetInstallationVersion(&bstrVersion))) {
    return false;
  }
  vsInstanceInfo.Version =
    cmsys::Encoding::ToNarrow(std::wstring(bstrVersion));

  // Reboot may have been required before the installation path was created.
  SmartBSTR bstrInstallationPath;
  if ((eLocal & state) == eLocal) {
    if (FAILED(pInstance->GetInstallationPath(&bstrInstallationPath))) {
      return false;
    }
    vsInstanceInfo.VSInstallLocation =
      cmsys::Encoding::ToNarrow(std::wstring(bstrInstallationPath));
    cmSystemTools::ConvertToUnixSlashes(vsInstanceInfo.VSInstallLocation);
  }

  // Check if a compiler is installed with this instance.
  if (!LoadVSInstanceVCToolsetVersion(vsInstanceInfo)) {
    return false;
  }

  // Reboot may have been required before the product package was registered
  // (last).
  if ((eRegistered & state) == eRegistered) {
    SmartCOMPtr<ISetupPackageReference> product;
    if (FAILED(pInstance->GetProduct(&product)) || !product) {
      return false;
    }

    LPSAFEARRAY lpsaPackages;
    if (FAILED(pInstance->GetPackages(&lpsaPackages)) ||
        lpsaPackages == nullptr) {
      return false;
    }

    int lower = lpsaPackages->rgsabound[0].lLbound;
    int upper = lpsaPackages->rgsabound[0].cElements + lower;

    IUnknown** ppData = (IUnknown**)lpsaPackages->pvData;
    for (int i = lower; i < upper; i++) {
      SmartCOMPtr<ISetupPackageReference> package = nullptr;
      if (FAILED(ppData[i]->QueryInterface(IID_ISetupPackageReference,
                                           (void**)&package)) ||
          package == nullptr) {
        continue;
      }

      bool win10SDKInstalled = false;
      bool win81SDkInstalled = false;
      bool ret =
        CheckInstalledComponent(package, win10SDKInstalled, win81SDkInstalled);
      if (ret) {
        vsInstanceInfo.IsWin10SDKInstalled |= win10SDKInstalled;
        vsInstanceInfo.IsWin81SDKInstalled |= win81SDkInstalled;
      }
    }

    SafeArrayDestroy(lpsaPackages);
  }

  return true;
}

bool cmVSSetupAPIHelper::GetVSInstanceInfo(std::string& vsInstallLocation)
{
  vsInstallLocation.clear();
  bool isInstalled = this->EnumerateAndChooseVSInstance();

  if (isInstalled) {
    vsInstallLocation = chosenInstanceInfo.GetInstallLocation();
  }

  return isInstalled;
}

bool cmVSSetupAPIHelper::GetVSInstanceVersion(std::string& vsInstanceVersion)
{
  vsInstanceVersion.clear();
  bool isInstalled = this->EnumerateAndChooseVSInstance();

  if (isInstalled) {
    vsInstanceVersion = chosenInstanceInfo.Version;
  }

  return isInstalled;
}

bool cmVSSetupAPIHelper::GetVCToolsetVersion(std::string& vsToolsetVersion)
{
  vsToolsetVersion.clear();
  bool isInstalled = this->EnumerateAndChooseVSInstance();

  if (isInstalled) {
    vsToolsetVersion = chosenInstanceInfo.VCToolsetVersion;
  }

  return isInstalled && !vsToolsetVersion.empty();
}

bool cmVSSetupAPIHelper::IsEWDKEnabled()
{
  std::string envEnterpriseWDK;
  std::string envDisableRegistryUse;
  cmSystemTools::GetEnv("EnterpriseWDK", envEnterpriseWDK);
  cmSystemTools::GetEnv("DisableRegistryUse", envDisableRegistryUse);
  if (!cmSystemTools::Strucmp(envEnterpriseWDK.c_str(), "True") &&
      !cmSystemTools::Strucmp(envDisableRegistryUse.c_str(), "True")) {
    return true;
  }

  return false;
}

#if !defined(CMAKE_BOOTSTRAP)
namespace {
std::string FindVsWhereCommand()
{
  std::string vswhere;
  static const char* programFiles[] = { "ProgramFiles(x86)", "ProgramFiles" };
  for (const char* pf : programFiles) {
    if (cmSystemTools::GetEnv(pf, vswhere)) {
      vswhere += "/Microsoft Visual Studio/Installer/vswhere.exe";
      if (cmSystemTools::FileExists(vswhere)) {
        return vswhere;
      }
    }
  }
  vswhere = "vswhere.exe";
  return vswhere;
}
}
#endif

bool cmVSSetupAPIHelper::EnumerateVSInstancesWithVswhere(
  std::vector<VSInstanceInfo>& VSInstances)
{
#if !defined(CMAKE_BOOTSTRAP)
  // Construct vswhere command to get installed VS instances in JSON format
  std::string vswhereExe = FindVsWhereCommand();
  std::vector<std::string> vswhereCmd = { vswhereExe, "-format", "json" };

  // Execute vswhere command and capture JSON output
  std::string json_output;
  int retVal = 1;
  if (!cmSystemTools::RunSingleCommand(vswhereCmd, &json_output, &json_output,
                                       &retVal, nullptr,
                                       cmSystemTools::OUTPUT_NONE)) {
    return false;
  }

  // Parse JSON output and iterate over elements
  Json::CharReaderBuilder builder;
  auto jsonReader = std::unique_ptr<Json::CharReader>(builder.newCharReader());
  Json::Value json;
  std::string error;

  if (!jsonReader->parse(json_output.data(),
                         json_output.data() + json_output.size(), &json,
                         &error)) {
    return false;
  }

  for (const auto& item : json) {
    VSInstanceInfo instance;
    instance.Version = item["installationVersion"].asString();
    instance.VSInstallLocation = item["installationPath"].asString();
    instance.IsWin10SDKInstalled = true;
    instance.IsWin81SDKInstalled = false;
    cmSystemTools::ConvertToUnixSlashes(instance.VSInstallLocation);
    if (LoadVSInstanceVCToolsetVersion(instance)) {
      VSInstances.push_back(instance);
    }
  }
  return true;
#else
  static_cast<void>(VSInstances);
  return false;
#endif
}

bool cmVSSetupAPIHelper::EnumerateVSInstancesWithCOM(
  std::vector<VSInstanceInfo>& VSInstances)
{
  if (initializationFailure || setupConfig == nullptr ||
      setupConfig2 == nullptr || setupHelper == nullptr) {
    return false;
  }

  SmartCOMPtr<IEnumSetupInstances> enumInstances = nullptr;
  if (FAILED(
        setupConfig2->EnumInstances((IEnumSetupInstances**)&enumInstances)) ||
      !enumInstances) {
    return false;
  }

  SmartCOMPtr<ISetupInstance> instance;
  while (SUCCEEDED(enumInstances->Next(1, &instance, nullptr)) && instance) {
    SmartCOMPtr<ISetupInstance2> instance2 = nullptr;
    if (FAILED(
          instance->QueryInterface(IID_ISetupInstance2, (void**)&instance2)) ||
        !instance2) {
      instance = nullptr;
      continue;
    }

    VSInstanceInfo instanceInfo;
    bool isInstalled = GetVSInstanceInfo(instance2, instanceInfo);
    instance = instance2 = nullptr;
    if (isInstalled) {
      VSInstances.push_back(instanceInfo);
    }
  }
  return true;
}

bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
{
  bool isVSInstanceExists = false;
  if (!chosenInstanceInfo.VSInstallLocation.empty()) {
    return true;
  }

  if (this->IsEWDKEnabled()) {
    std::string envWindowsSdkDir81;
    std::string envVSVersion;
    std::string envVsInstallDir;

    cmSystemTools::GetEnv("WindowsSdkDir_81", envWindowsSdkDir81);
    cmSystemTools::GetEnv("VisualStudioVersion", envVSVersion);
    cmSystemTools::GetEnv("VSINSTALLDIR", envVsInstallDir);
    if (envVSVersion.empty() || envVsInstallDir.empty()) {
      return false;
    }

    chosenInstanceInfo.VSInstallLocation = envVsInstallDir;
    chosenInstanceInfo.Version = envVSVersion;
    if (!LoadVSInstanceVCToolsetVersion(chosenInstanceInfo)) {
      return false;
    }
    chosenInstanceInfo.IsWin10SDKInstalled = true;
    chosenInstanceInfo.IsWin81SDKInstalled = !envWindowsSdkDir81.empty();
    return true;
  }

  std::string envVSCommonToolsDir;
  std::string envVSCommonToolsDirEnvName =
    cmStrCat("VS", std::to_string(this->Version), "0COMNTOOLS");

  if (cmSystemTools::GetEnv(envVSCommonToolsDirEnvName.c_str(),
                            envVSCommonToolsDir)) {
    cmSystemTools::ConvertToUnixSlashes(envVSCommonToolsDir);
  }

  std::string const wantVersion = cmStrCat(std::to_string(this->Version), '.');

  bool specifiedLocationNotSpecifiedVersion = false;

  SmartCOMPtr<ISetupInstance> instance;

  std::vector<VSInstanceInfo> vecVSInstancesAll;

  // Enumerate VS instances with either COM interface or Vswhere
  if (!EnumerateVSInstancesWithCOM(vecVSInstancesAll) &&
      !EnumerateVSInstancesWithVswhere(vecVSInstancesAll)) {
    return false;
  }

  std::vector<VSInstanceInfo> vecVSInstances;
  for (const auto& instanceInfo : vecVSInstancesAll) {
    // We are looking for a specific major version.
    if (instanceInfo.Version.size() < wantVersion.size() ||
        instanceInfo.Version.substr(0, wantVersion.size()) != wantVersion) {
      continue;
    }

    if (!this->SpecifiedVSInstallLocation.empty()) {
      // We are looking for a specific instance.
      std::string currentVSLocation = instanceInfo.GetInstallLocation();
      if (cmSystemTools::ComparePath(currentVSLocation,
                                     this->SpecifiedVSInstallLocation)) {
        if (this->SpecifiedVSInstallVersion.empty() ||
            instanceInfo.Version == this->SpecifiedVSInstallVersion) {
          chosenInstanceInfo = instanceInfo;
          return true;
        }
        specifiedLocationNotSpecifiedVersion = true;
      }
    } else if (!this->SpecifiedVSInstallVersion.empty()) {
      // We are looking for a specific version.
      if (instanceInfo.Version == this->SpecifiedVSInstallVersion) {
        chosenInstanceInfo = instanceInfo;
        return true;
      }
    } else {
      // We are not looking for a specific instance.
      // If we've been given a hint then use it.
      if (!envVSCommonToolsDir.empty()) {
        std::string currentVSLocation =
          cmStrCat(instanceInfo.GetInstallLocation(), "/Common7/Tools");
        if (cmSystemTools::ComparePath(currentVSLocation,
                                       envVSCommonToolsDir)) {
          chosenInstanceInfo = instanceInfo;
          return true;
        }
      }
      // Otherwise, add this to the list of candidates.
      vecVSInstances.push_back(instanceInfo);
    }
  }

  if (!this->SpecifiedVSInstallLocation.empty() &&
      !specifiedLocationNotSpecifiedVersion) {
    // The VS Installer does not know about the specified location.
    // Check for one directly on disk.
    return this->LoadSpecifiedVSInstanceFromDisk();
  }

  if (!vecVSInstances.empty()) {
    isVSInstanceExists = true;
    int index = ChooseVSInstance(vecVSInstances);
    chosenInstanceInfo = vecVSInstances[index];
  }

  return isVSInstanceExists;
}

int cmVSSetupAPIHelper::ChooseVSInstance(
  const std::vector<VSInstanceInfo>& vecVSInstances)
{
  if (vecVSInstances.empty()) {
    return -1;
  }

  if (vecVSInstances.size() == 1) {
    return 0;
  }

  unsigned int chosenIndex = 0;
  for (unsigned int i = 1; i < vecVSInstances.size(); i++) {
    // If the current has Win10 SDK but not the chosen one, then choose the
    // current VS instance
    if (!vecVSInstances[chosenIndex].IsWin10SDKInstalled &&
        vecVSInstances[i].IsWin10SDKInstalled) {
      chosenIndex = i;
      continue;
    }

    // If the chosen one has Win10 SDK but the current one is not, then look at
    // the next VS instance even the current
    // instance version may be higher
    if (vecVSInstances[chosenIndex].IsWin10SDKInstalled &&
        !vecVSInstances[i].IsWin10SDKInstalled) {
      continue;
    }

    // If both chosen one and current one doesn't have Win10 SDK but the
    // current one has Win8.1 SDK installed,
    // then choose the current one
    if (!vecVSInstances[chosenIndex].IsWin10SDKInstalled &&
        !vecVSInstances[i].IsWin10SDKInstalled &&
        !vecVSInstances[chosenIndex].IsWin81SDKInstalled &&
        vecVSInstances[i].IsWin81SDKInstalled) {
      chosenIndex = i;
      continue;
    }

    // If there is no difference in WinSDKs then look for the highest version
    // of installed VS
    if ((vecVSInstances[chosenIndex].IsWin10SDKInstalled ==
         vecVSInstances[i].IsWin10SDKInstalled) &&
        (vecVSInstances[chosenIndex].IsWin81SDKInstalled ==
         vecVSInstances[i].IsWin81SDKInstalled) &&
        vecVSInstances[chosenIndex].Version < vecVSInstances[i].Version) {
      chosenIndex = i;
      continue;
    }
  }

  return chosenIndex;
}

bool cmVSSetupAPIHelper::LoadSpecifiedVSInstanceFromDisk()
{
  if (!cmSystemTools::FileIsDirectory(this->SpecifiedVSInstallLocation)) {
    return false;
  }
  VSInstanceInfo vsInstanceInfo;
  vsInstanceInfo.VSInstallLocation = this->SpecifiedVSInstallLocation;
  // FIXME: Is there a better way to get SDK information?
  vsInstanceInfo.IsWin10SDKInstalled = true;
  vsInstanceInfo.IsWin81SDKInstalled = false;

  if (!this->SpecifiedVSInstallVersion.empty()) {
    // Assume the version specified by the user is correct.
    vsInstanceInfo.Version = this->SpecifiedVSInstallVersion;
  } else {
    return false;
  }

  if (!LoadVSInstanceVCToolsetVersion(vsInstanceInfo)) {
    return false;
  }

  chosenInstanceInfo = std::move(vsInstanceInfo);
  return true;
}

bool cmVSSetupAPIHelper::Initialize()
{
  if (initializationFailure) {
    return false;
  }

  if (FAILED(comInitialized)) {
    initializationFailure = true;
    return false;
  }

  if (FAILED(setupConfig.CoCreateInstance(CLSID_SetupConfiguration, nullptr,
                                          IID_ISetupConfiguration,
                                          CLSCTX_INPROC_SERVER)) ||
      setupConfig == nullptr) {
    initializationFailure = true;
    return false;
  }

  if (FAILED(setupConfig.QueryInterface(IID_ISetupConfiguration2,
                                        (void**)&setupConfig2)) ||
      setupConfig2 == nullptr) {
    initializationFailure = true;
    return false;
  }

  if (FAILED(
        setupConfig.QueryInterface(IID_ISetupHelper, (void**)&setupHelper)) ||
      setupHelper == nullptr) {
    initializationFailure = true;
    return false;
  }

  initializationFailure = false;
  return true;
}
