// 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 "src/dawn/node/binding/GPU.h"

#include <algorithm>
#include <cstdlib>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include "dawn/webgpu_cpp_print.h"
#include "src/dawn/node/binding/Converter.h"
#include "src/dawn/node/binding/GPUAdapter.h"
#include "src/dawn/node/binding/TogglesLoader.h"

#if defined(_WIN32)
#include <Windows.h>
#endif

namespace {
std::string GetEnvVar(const char* varName) {
#if defined(_WIN32)
    // Use _dupenv_s to avoid unsafe warnings about std::getenv
    char* value = nullptr;
    _dupenv_s(&value, nullptr, varName);
    if (value) {
        std::string result = value;
        free(value);
        return result;
    }
    return "";
#else
    if (auto* val = std::getenv(varName)) {
        return val;
    }
    return "";
#endif
}

void SetDllDir(const char* dir) {
    (void)dir;
#if defined(_WIN32)
    ::SetDllDirectory(dir);
#endif
}

struct BackendInfo {
    const char* const name;
    const char* const alias;  // may be nullptr
    wgpu::BackendType const backend;
};

constexpr BackendInfo kBackends[] = {
    {"null", nullptr, wgpu::BackendType::Null},         //
    {"webgpu", nullptr, wgpu::BackendType::WebGPU},     //
    {"d3d11", nullptr, wgpu::BackendType::D3D11},       //
    {"d3d12", "d3d", wgpu::BackendType::D3D12},         //
    {"metal", nullptr, wgpu::BackendType::Metal},       //
    {"vulkan", "vk", wgpu::BackendType::Vulkan},        //
    {"opengl", "gl", wgpu::BackendType::OpenGL},        //
    {"opengles", "gles", wgpu::BackendType::OpenGLES},  //
};

std::optional<wgpu::BackendType> ParseBackend(std::string_view name) {
    for (auto& info : kBackends) {
        if (info.name == name || (info.alias && info.alias == name)) {
            return info.backend;
        }
    }
    return std::nullopt;
}

const char* BackendName(wgpu::BackendType backend) {
    for (auto& info : kBackends) {
        if (info.backend == backend) {
            return info.name;
        }
    }
    return "<unknown>";
}

}  // namespace

namespace wgpu::binding {

////////////////////////////////////////////////////////////////////////////////
// wgpu::bindings::GPU
////////////////////////////////////////////////////////////////////////////////
GPU::GPU(Flags flags) : flags_(std::move(flags)) {
    // Setting the DllDir changes where we load adapter DLLs from (e.g. d3dcompiler_47.dll)
    if (auto dir = flags_.Get("dlldir")) {
        SetDllDir(dir->c_str());
    }

    // Set up the chained descriptor for the various instance extensions.
    dawn::native::DawnInstanceDescriptor dawnDesc;
    if (auto validate = flags_.Get("validate"); validate == "1" || validate == "true") {
        dawnDesc.backendValidationLevel = dawn::native::BackendValidationLevel::Full;
    }

    TogglesLoader togglesLoader(flags_);
    DawnTogglesDescriptor togglesDesc = togglesLoader.GetDescriptor();
    togglesDesc.nextInChain = &dawnDesc;

    wgpu::InstanceDescriptor desc;
    desc.nextInChain = &togglesDesc;
    instance_ = std::make_unique<dawn::native::Instance>(
        reinterpret_cast<const WGPUInstanceDescriptor*>(&desc));
    async_ = AsyncRunner::Create(instance_.get());
}

interop::Promise<std::optional<interop::Interface<interop::GPUAdapter>>> GPU::requestAdapter(
    Napi::Env env,
    interop::GPURequestAdapterOptions options) {
    auto promise =
        interop::Promise<std::optional<interop::Interface<interop::GPUAdapter>>>(env, PROMISE_INFO);

    RequestAdapterOptions nativeOptions;
    nativeOptions.forceFallbackAdapter = options.forceFallbackAdapter;
    nativeOptions.compatibilityMode = options.compatibilityMode;

    // Convert the power preference.
    nativeOptions.powerPreference = PowerPreference::Undefined;
    if (options.powerPreference.has_value()) {
        switch (options.powerPreference.value()) {
            case interop::GPUPowerPreference::kLowPower:
                nativeOptions.powerPreference = PowerPreference::LowPower;
                break;
            case interop::GPUPowerPreference::kHighPerformance:
                nativeOptions.powerPreference = PowerPreference::HighPerformance;
                break;
        }
    }

    // Choose the backend to use.
#if defined(_WIN32)
    constexpr auto kDefaultBackendType = wgpu::BackendType::D3D12;
#elif defined(__linux__)
    constexpr auto kDefaultBackendType = wgpu::BackendType::Vulkan;
#elif defined(__APPLE__)
    constexpr auto kDefaultBackendType = wgpu::BackendType::Metal;
#else
#error "Unsupported platform"
#endif
    nativeOptions.backendType = kDefaultBackendType;

    // Check for backend override from env var / flag.
    std::string forceBackend;
    if (auto f = flags_.Get("backend")) {
        forceBackend = *f;
    } else if (std::string envVar = GetEnvVar("DAWNNODE_BACKEND"); !envVar.empty()) {
        forceBackend = envVar;
    }
    std::transform(forceBackend.begin(), forceBackend.end(), forceBackend.begin(),
                   [](char c) { return std::tolower(c); });

    if (!forceBackend.empty()) {
        if (auto parsed = ParseBackend(forceBackend)) {
            nativeOptions.backendType = parsed.value();
        } else {
            std::stringstream msg;
            msg << "unrecognised backend '" << forceBackend << "'\nPossible backends : ";
            for (auto& info : kBackends) {
                if (&info != &kBackends[0]) {
                    msg << ", ";
                }
                msg << "'" << info.name << "'";
            }
            promise.Reject(msg.str());
            return promise;
        }
    }

    // Propagate toggles.
    TogglesLoader togglesLoader(flags_);
    DawnTogglesDescriptor togglesDescriptor = togglesLoader.GetDescriptor();
    nativeOptions.nextInChain = &togglesDescriptor;

    auto adapters = instance_->EnumerateAdapters(&nativeOptions);
    if (adapters.empty()) {
        promise.Resolve({});
        return promise;
    }

    // Check for specific adapter device name.
    // This was AdapterProperties.name, now it is AdapterInfo.device.
    std::string deviceName;
    if (auto f = flags_.Get("adapter")) {
        deviceName = *f;
    }

    dawn::native::Adapter* adapter = nullptr;
    for (auto& a : adapters) {
        wgpu::AdapterInfo info;
        a.GetInfo(&info);

        if (!deviceName.empty() &&
            std::string_view(info.device).find(deviceName) == std::string::npos) {
            continue;
        }

        adapter = &a;
        break;
    }

    if (!adapter) {
        std::stringstream msg;
        if (!forceBackend.empty() || deviceName.empty()) {
            msg << "no adapter ";
            if (!forceBackend.empty()) {
                msg << "with backend '" << forceBackend << "'";
                if (!deviceName.empty()) {
                    msg << " and name '" << deviceName << "'";
                }
            } else {
                msg << " with name '" << deviceName << "'";
            }
            msg << " found";
        } else {
            msg << "no suitable backends found";
        }
        msg << "\nAvailable adapters:";
        for (auto& a : adapters) {
            wgpu::AdapterInfo info;
            a.GetInfo(&info);
            msg << "\n * backend: '" << BackendName(info.backendType) << "', name: '" << info.device
                << "'";
        }
        promise.Reject(msg.str());
        return promise;
    }

    if (flags_.Get("verbose")) {
        wgpu::AdapterInfo info;
        adapter->GetInfo(&info);
        std::cout << "using GPU adapter: " << info.device << "\n";
    }

    auto gpuAdapter = GPUAdapter::Create<GPUAdapter>(env, *adapter, flags_, async_);
    promise.Resolve(std::optional<interop::Interface<interop::GPUAdapter>>(gpuAdapter));
    return promise;
}

interop::GPUTextureFormat GPU::getPreferredCanvasFormat(Napi::Env) {
#if defined(__ANDROID__)
    return interop::GPUTextureFormat::kRgba8Unorm;
#else
    return interop::GPUTextureFormat::kBgra8Unorm;
#endif  // defined(__ANDROID__)
}

interop::Interface<interop::WGSLLanguageFeatures> GPU::getWgslLanguageFeatures(Napi::Env env) {
    using InteropWGSLFeatureSet = std::unordered_set<interop::WGSLFeatureName>;

    struct Features : public interop::WGSLLanguageFeatures {
        explicit Features(InteropWGSLFeatureSet features) : features_(features) {}
        ~Features() = default;

        bool has(Napi::Env env, std::string name) {
            interop::WGSLFeatureName feature;
            if (!interop::Converter<interop::WGSLFeatureName>::FromString(name, feature)) {
                return false;
            }
            return features_.count(feature);
        }
        std::vector<std::string> keys(Napi::Env env) {
            std::vector<std::string> out;
            out.reserve(features_.size());
            for (auto feature : features_) {
                out.push_back(interop::Converter<interop::WGSLFeatureName>::ToString(feature));
            }
            return out;
        }
        size_t getSize(Napi::Env env) { return features_.size(); }

        InteropWGSLFeatureSet features_;
    };

    wgpu::Instance instance = instance_->Get();
    size_t count = instance.EnumerateWGSLLanguageFeatures(nullptr);

    std::vector<wgpu::WGSLFeatureName> features(count);
    instance.EnumerateWGSLLanguageFeatures(features.data());

    // Add all known WGSLLangaugeFeatures known by dawn.node but warn loudly when there are unknown
    // ones.
    InteropWGSLFeatureSet featureSet;
    Converter conv(env);
    for (auto feature : features) {
        interop::WGSLFeatureName wgslFeature;
        if (conv(wgslFeature, feature)) {
            featureSet.emplace(wgslFeature);
        } else {
            LOG("Unknown WGSLFeatureName ", feature);
        }
    }

    return interop::WGSLLanguageFeatures::Create<Features>(env, std::move(featureSet));
}

}  // namespace wgpu::binding
