// Copyright 2023 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "dawn/native/d3d/PlatformFunctions.h"

#include <comdef.h>
#include <versionhelpers.h>

#include <vector>

#include "dawn/common/SystemUtils.h"

namespace dawn::native::d3d {

namespace {
// Referenced from base/win/registry.cc in Chromium
uint64_t ReadFromSZRegistryKey(HKEY registerKey, const char* registerKeyName) {
    DWORD valueType;
    DWORD returnSize;
    if (RegQueryValueExA(registerKey, registerKeyName, nullptr, &valueType, nullptr, &returnSize) !=
        ERROR_SUCCESS) {
        return 0;
    }
    std::vector<char> returnStringValue(returnSize);
    auto hr = RegQueryValueExA(registerKey, registerKeyName, nullptr, &valueType,
                               reinterpret_cast<LPBYTE>(returnStringValue.data()), &returnSize);
    if (hr != ERROR_SUCCESS || valueType != REG_SZ) {
        return 0;
    }
    constexpr int32_t kRadix = 10;
    return strtol(returnStringValue.data(), nullptr, kRadix);
}

}  // anonymous namespace

PlatformFunctions::PlatformFunctions() : mCurrentBuildNumber(0) {}

PlatformFunctions::~PlatformFunctions() = default;

MaybeError PlatformFunctions::Initialize() {
    DAWN_TRY(LoadDXGI());
    InitWindowsVersion();
    return {};
}

MaybeError PlatformFunctions::LoadDXGI() {
#if DAWN_PLATFORM_IS(WINUWP)
#if defined(_DEBUG)
    // DXGIGetDebugInterface1 is tagged as a development-only capability
    // which implies that linking to this function will cause
    // the application to fail Windows store certification
    // But we need it when debuging using VS Graphics Diagnostics or PIX
    // So we only link to it in debug build
    dxgiGetDebugInterface1 = &DXGIGetDebugInterface1;
#endif
    createDxgiFactory2 = &CreateDXGIFactory2;
#else
    std::string error;
    if (!mDXGILib.OpenSystemLibrary(L"dxgi.dll", &error) ||
        !mDXGILib.GetProc(&dxgiGetDebugInterface1, "DXGIGetDebugInterface1", &error) ||
        !mDXGILib.GetProc(&createDxgiFactory2, "CreateDXGIFactory2", &error)) {
        return DAWN_INTERNAL_ERROR(error.c_str());
    }
#endif

    return {};
}

MaybeError PlatformFunctions::EnsureFXC(std::span<const std::string> searchPaths) {
    if (mFXCompilerLib.Valid()) {
        // The library is already loaded, no need to load it again.
        return {};
    }

#if DAWN_PLATFORM_IS(WINUWP)
    d3dCompile = &D3DCompile;
    d3dDisassemble = &D3DDisassemble;
#else
    std::string error;
#if defined(DAWN_FORCE_SYSTEM_COMPONENT_LOAD)
    // https://crbug.com/399358291. Since Skia's build system is not able to locate the Windows
    // SDK tools, d3dcompiler_47.dll is not copied into the build location. Tests fail when we
    // prepend the module directory to the path. To address this, we fallback to the compiler
    // that comes with the OS. The OS compiler contains functionality and heap corruption bugs
    // on older Windows versions so care must be taken to always ship with the latest SDK
    // compiler.
    const bool loadSuccess = mFXCompilerLib.OpenSystemLibrary(L"d3dcompiler_47.dll", &error);
#else
    const bool loadSuccess = mFXCompilerLib.Open("d3dcompiler_47.dll", searchPaths, &error);
#endif
    if (!loadSuccess || !mFXCompilerLib.GetProc(&d3dCompile, "D3DCompile", &error) ||
        !mFXCompilerLib.GetProc(&d3dDisassemble, "D3DDisassemble", &error)) {
        return DAWN_INTERNAL_ERROR(error.c_str());
    }
#endif
    return {};
}

void PlatformFunctions::InitWindowsVersion() {
    // Currently we only care about the build number of Windows 10 and Windows 11.
    if (!IsWindows10OrGreater()) {
        return;
    }

    // Referenced from base/win/windows_version.cc in Chromium
    constexpr wchar_t kRegKeyWindowsNTCurrentVersion[] =
        L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";

    HKEY hKey;
    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, kRegKeyWindowsNTCurrentVersion, 0, KEY_QUERY_VALUE,
                      &hKey) != ERROR_SUCCESS) {
        return;
    }

    mCurrentBuildNumber = ReadFromSZRegistryKey(hKey, "CurrentBuildNumber");

    RegCloseKey(hKey);
}

uint64_t PlatformFunctions::GetWindowsBuildNumber() const {
    return mCurrentBuildNumber;
}

}  // namespace dawn::native::d3d
