// Copyright 2021 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 <string>

#include "src/tint/lang/hlsl/validate/validate.h"

#include "src/tint/utils/command/command.h"
#include "src/tint/utils/file/tmpfile.h"
#include "src/tint/utils/macros/defer.h"
#include "src/tint/utils/text/string.h"

#ifdef _WIN32
#include <Windows.h>
#include <atlbase.h>
#include <d3dcommon.h>
#include <d3dcompiler.h>
#include <wrl.h>
#else
#include <dlfcn.h>
#endif  // _WIN32

// dxc headers
TINT_BEGIN_DISABLE_ALL_WARNINGS();
#ifdef __clang__
// # Use UUID emulation with clang to avoid compiling with ms-extensions
#define __EMULATE_UUID
#endif
#include "dxc/dxcapi.h"
TINT_END_DISABLE_ALL_WARNINGS();

// Disable warnings about old-style casts which result from using
// the SUCCEEDED and FAILED macros that C-style cast to HRESULT.
TINT_DISABLE_WARNING_OLD_STYLE_CAST

namespace {
using PFN_DXC_CREATE_INSTANCE = HRESULT(__stdcall*)(REFCLSID rclsid,
                                                    REFIID riid,
                                                    LPVOID* ppCompiler);

// Wrap the call to DxcCreateInstance via the dlsym-loaded function pointer
// to disable UBSAN on it. This is to workaround a known UBSAN false
// positive: https://github.com/google/sanitizers/issues/911
DAWN_NO_SANITIZE("undefined")
HRESULT CallDxcCreateInstance(PFN_DXC_CREATE_INSTANCE dxc_create_instance,
                              CComPtr<IDxcCompiler3>& dxc_compiler) {
    return dxc_create_instance(CLSID_DxcCompiler, IID_PPV_ARGS(&dxc_compiler));
}
}  // namespace

namespace tint::hlsl::validate {

Result ValidateUsingDXC(const std::string& dxc_path,
                        const std::string& source,
                        const EntryPointList& entry_points,
                        bool require_16bit_types,
                        uint32_t hlsl_shader_model) {
    Result result;

    if (entry_points.empty()) {
        result.output = "No entrypoint found";
        result.failed = true;
        return result;
    }

    // Native 16-bit types, e.g. float16_t, require SM6.2. Otherwise we use SM6.0.
    if (hlsl_shader_model < 60 || hlsl_shader_model > 66) {
        result.output = "Invalid HLSL shader model " + std::to_string(hlsl_shader_model);
        result.failed = true;
        return result;
    }
    if (require_16bit_types && hlsl_shader_model < 62) {
        result.output = "The HLSL shader model " + std::to_string(hlsl_shader_model) +
                        " is not enough for float16_t.";
        result.failed = true;
        return result;
    }

#define CHECK_HR(hr, error_msg)        \
    do {                               \
        if (FAILED(hr)) {              \
            result.output = error_msg; \
            result.failed = true;      \
            return result;             \
        }                              \
    } while (false)

    HRESULT hr;

    // Load the dll and get the DxcCreateInstance function
    PFN_DXC_CREATE_INSTANCE dxc_create_instance = nullptr;
#ifdef _WIN32
    HMODULE dxcLib = LoadLibraryA(dxc_path.c_str());
    if (dxcLib == nullptr) {
        result.output = "Failed to load dxc: " + dxc_path;
        result.failed = true;
        return result;
    }
    // Avoid ASAN false positives when unloading DLL: https://github.com/google/sanitizers/issues/89
#if !DAWN_ASAN_ENABLED()
    TINT_DEFER({ FreeLibrary(dxcLib); });
#endif

    dxc_create_instance =
        reinterpret_cast<PFN_DXC_CREATE_INSTANCE>(GetProcAddress(dxcLib, "DxcCreateInstance"));
#else
    void* dxcLib = dlopen(dxc_path.c_str(), RTLD_LAZY | RTLD_GLOBAL);
    if (dxcLib == nullptr) {
        result.output = "Failed to load dxc: " + dxc_path;
        result.failed = true;
        return result;
    }
    // Avoid ASAN false positives when unloading DLL: https://github.com/google/sanitizers/issues/89
#if !DAWN_ASAN_ENABLED()
    TINT_DEFER({ dlclose(dxcLib); });
#endif

    dxc_create_instance =
        reinterpret_cast<PFN_DXC_CREATE_INSTANCE>(dlsym(dxcLib, "DxcCreateInstance"));
#endif
    if (dxc_create_instance == nullptr) {
        result.output = "GetProcAccess failed";
        result.failed = true;
        return result;
    }

    CComPtr<IDxcCompiler3> dxc_compiler;
    hr = CallDxcCreateInstance(dxc_create_instance, dxc_compiler);
    CHECK_HR(hr, "DxcCreateInstance failed");

    for (auto ep : entry_points) {
        const wchar_t* stage_prefix = L"";
        switch (ep.second) {
            case ast::PipelineStage::kNone:
                result.output = "Invalid PipelineStage";
                result.failed = true;
                return result;
            case ast::PipelineStage::kVertex:
                stage_prefix = L"vs";
                break;
            case ast::PipelineStage::kFragment:
                stage_prefix = L"ps";
                break;
            case ast::PipelineStage::kCompute:
                stage_prefix = L"cs";
                break;
        }

        // Match Dawn's compile flags
        // See dawn\src\dawn_native\d3d12\RenderPipelineD3D12.cpp
        // and dawn_native\d3d\ShaderUtils.cpp (GetDXCArguments)
        std::wstring shader_model_version = std::to_wstring(hlsl_shader_model / 10) + L"_" +
                                            std::to_wstring(hlsl_shader_model % 10);
        std::wstring profile = std::wstring(stage_prefix) + L"_" + shader_model_version;
        std::wstring entry_point = std::wstring(ep.first.begin(), ep.first.end());
        std::vector<const wchar_t*> args{
            L"-T",                                              // Profile
            profile.c_str(),                                    //
            L"-HV 2018",                                        // Use HLSL 2018
            L"-E",                                              // Entry point
            entry_point.c_str(),                                //
            L"/Zpr",                                            // D3DCOMPILE_PACK_MATRIX_ROW_MAJOR
            L"/Gis",                                            // D3DCOMPILE_IEEE_STRICTNESS
            require_16bit_types ? L"-enable-16bit-types" : L""  // Enable 16-bit if required
        };

        DxcBuffer source_buffer;
        source_buffer.Ptr = source.c_str();
        source_buffer.Size = source.length();
        source_buffer.Encoding = DXC_CP_UTF8;
        CComPtr<IDxcResult> compile_result;
        hr = dxc_compiler->Compile(&source_buffer, args.data(), static_cast<UINT32>(args.size()),
                                   nullptr, IID_PPV_ARGS(&compile_result));
        CHECK_HR(hr, "Compile call failed");

        HRESULT compile_status;
        hr = compile_result->GetStatus(&compile_status);
        CHECK_HR(hr, "GetStatus call failed");

        if (FAILED(compile_status)) {
            CComPtr<IDxcBlobEncoding> errors;
            hr = compile_result->GetErrorBuffer(&errors);
            CHECK_HR(hr, "GetErrorBuffer call failed");
            result.output = static_cast<char*>(errors->GetBufferPointer());
            result.failed = true;
            return result;
        }

        // Compilation succeeded, get compiled shader blob and disassamble it
        CComPtr<IDxcBlob> compiled_shader;
        hr = compile_result->GetResult(&compiled_shader);
        CHECK_HR(hr, "GetResult call failed");

        DxcBuffer compiled_shader_buffer;
        compiled_shader_buffer.Ptr = compiled_shader->GetBufferPointer();
        compiled_shader_buffer.Size = compiled_shader->GetBufferSize();
        compiled_shader_buffer.Encoding = DXC_CP_UTF8;
        CComPtr<IDxcResult> dis_result;
        hr = dxc_compiler->Disassemble(&compiled_shader_buffer, IID_PPV_ARGS(&dis_result));
        CHECK_HR(hr, "Disassemble call failed");

        CComPtr<IDxcBlobEncoding> disassembly;
        if ((dis_result != nullptr) && dis_result->HasOutput(DXC_OUT_DISASSEMBLY) &&
            SUCCEEDED(
                dis_result->GetOutput(DXC_OUT_DISASSEMBLY, IID_PPV_ARGS(&disassembly), nullptr))) {
            result.output = static_cast<char*>(disassembly->GetBufferPointer());
        } else {
            result.output = "Failed to disassemble shader";
        }
    }

    return result;
}

#ifdef _WIN32
Result ValidateUsingFXC(const std::string& fxc_path,
                        const std::string& source,
                        const EntryPointList& entry_points) {
    Result result;

    if (entry_points.empty()) {
        result.output = "No entrypoint found";
        result.failed = true;
        return result;
    }

    // This library leaks if an error happens in this function, but it is ok
    // because it is loaded at most once, and the executables using UsingFXC
    // are short-lived.
    HMODULE fxcLib = LoadLibraryA(fxc_path.c_str());
    if (fxcLib == nullptr) {
        result.output = "Couldn't load FXC";
        result.failed = true;
        return result;
    }

    auto* d3dCompile = reinterpret_cast<pD3DCompile>(
        reinterpret_cast<void*>(GetProcAddress(fxcLib, "D3DCompile")));
    auto* d3dDisassemble = reinterpret_cast<pD3DDisassemble>(
        reinterpret_cast<void*>(GetProcAddress(fxcLib, "D3DDisassemble")));

    if (d3dCompile == nullptr) {
        result.output = "Couldn't load D3DCompile from FXC";
        result.failed = true;
        return result;
    }
    if (d3dDisassemble == nullptr) {
        result.output = "Couldn't load D3DDisassemble from FXC";
        result.failed = true;
        return result;
    }

    for (auto ep : entry_points) {
        const char* profile = "";
        switch (ep.second) {
            case ast::PipelineStage::kNone:
                result.output = "Invalid PipelineStage";
                result.failed = true;
                return result;
            case ast::PipelineStage::kVertex:
                profile = "vs_5_1";
                break;
            case ast::PipelineStage::kFragment:
                profile = "ps_5_1";
                break;
            case ast::PipelineStage::kCompute:
                profile = "cs_5_1";
                break;
        }

        // Match Dawn's compile flags
        // See dawn\src\dawn_native\d3d12\RenderPipelineD3D12.cpp
        UINT compileFlags = D3DCOMPILE_OPTIMIZATION_LEVEL0 | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR |
                            D3DCOMPILE_IEEE_STRICTNESS;

        CComPtr<ID3DBlob> compiledShader;
        CComPtr<ID3DBlob> errors;
        HRESULT res = d3dCompile(source.c_str(),    // pSrcData
                                 source.length(),   // SrcDataSize
                                 nullptr,           // pSourceName
                                 nullptr,           // pDefines
                                 nullptr,           // pInclude
                                 ep.first.c_str(),  // pEntrypoint
                                 profile,           // pTarget
                                 compileFlags,      // Flags1
                                 0,                 // Flags2
                                 &compiledShader,   // ppCode
                                 &errors);          // ppErrorMsgs
        if (FAILED(res)) {
            result.output = static_cast<char*>(errors->GetBufferPointer());
            result.failed = true;
            return result;
        } else {
            CComPtr<ID3DBlob> disassembly;
            res = d3dDisassemble(compiledShader->GetBufferPointer(),
                                 compiledShader->GetBufferSize(), 0, "", &disassembly);
            if (FAILED(res)) {
                result.output = "Failed to disassemble shader";
            } else {
                result.output = static_cast<char*>(disassembly->GetBufferPointer());
            }
        }
    }

    FreeLibrary(fxcLib);

    return result;
}
#endif  // _WIN32

}  // namespace tint::hlsl::validate
