// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/dawn_node/binding/GPU.h"

#include "src/dawn_node/binding/GPUAdapter.h"

#include <cstdlib>

#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
    }

}  // namespace

namespace wgpu { namespace binding {

    ////////////////////////////////////////////////////////////////////////////////
    // wgpu::bindings::GPU
    ////////////////////////////////////////////////////////////////////////////////
    GPU::GPU(Flags flags) : flags_(std::move(flags)) {
        // TODO: Disable in 'release'
        instance_.EnableBackendValidation(true);
        instance_.SetBackendValidationLevel(dawn_native::BackendValidationLevel::Full);

        // 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());
        }
        instance_.DiscoverDefaultAdapters();
    }

    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);

        if (options.forceFallbackAdapter) {
            // Software adapters are not currently supported.
            promise.Resolve({});
            return promise;
        }

        auto adapters = instance_.GetAdapters();
        if (adapters.empty()) {
            promise.Resolve({});
            return promise;
        }

#if defined(_WIN32)
        constexpr auto defaultBackendType = wgpu::BackendType::D3D12;
#elif defined(__linux__)
        constexpr auto defaultBackendType = wgpu::BackendType::Vulkan;
#elif defined(__APPLE__)
        constexpr auto defaultBackendType = wgpu::BackendType::Metal;
#else
#    error "Unsupported platform"
#endif

        auto targetBackendType = defaultBackendType;
        std::string forceBackend;

        // Check for override from env var
        if (std::string envVar = GetEnvVar("DAWNNODE_BACKEND"); !envVar.empty()) {
            forceBackend = envVar;
        }

        // Check for override from flag
        if (auto f = flags_.Get("dawn-backend")) {
            forceBackend = *f;
        }

        std::transform(forceBackend.begin(), forceBackend.end(), forceBackend.begin(),
                       [](char c) { return std::tolower(c); });

        // Default to first adapter if a backend is not specified
        size_t adapterIndex = 0;

        if (!forceBackend.empty()) {
            if (forceBackend == "null") {
                targetBackendType = wgpu::BackendType::Null;
            } else if (forceBackend == "webgpu") {
                targetBackendType = wgpu::BackendType::WebGPU;
            } else if (forceBackend == "d3d11") {
                targetBackendType = wgpu::BackendType::D3D11;
            } else if (forceBackend == "d3d12" || forceBackend == "d3d") {
                targetBackendType = wgpu::BackendType::D3D12;
            } else if (forceBackend == "metal") {
                targetBackendType = wgpu::BackendType::Metal;
            } else if (forceBackend == "vulkan" || forceBackend == "vk") {
                targetBackendType = wgpu::BackendType::Vulkan;
            } else if (forceBackend == "opengl" || forceBackend == "gl") {
                targetBackendType = wgpu::BackendType::OpenGL;
            } else if (forceBackend == "opengles" || forceBackend == "gles") {
                targetBackendType = wgpu::BackendType::OpenGLES;
            } else {
                promise.Reject("unknown backend '" + forceBackend + "'");
                return promise;
            }

            bool found = false;
            for (size_t i = 0; i < adapters.size(); ++i) {
                wgpu::AdapterProperties props;
                adapters[i].GetProperties(&props);
                if (props.backendType == targetBackendType) {
                    adapterIndex = i;
                    found = true;
                    break;
                }
            }
            if (!found) {
                promise.Reject("backend '" + forceBackend + "' not found");
                return promise;
            }
        }

        auto adapter = GPUAdapter::Create<GPUAdapter>(env, adapters[adapterIndex], flags_);
        promise.Resolve(std::optional<interop::Interface<interop::GPUAdapter>>(adapter));
        return promise;
    }

}}  // namespace wgpu::binding
