/*
 * Copyright 2022 Rive
 */

#include "testing_window.hpp"

#include "rive/rive_types.hpp"
#include <string>
#include <sstream>

#ifdef _WIN32
#include <windows.h>
#endif

#if defined(_WIN32) && !defined(RIVE_UNREAL)
extern "C"
{
    // https://stackoverflow.com/questions/68469954/how-to-choose-specific-gpu-when-create-opengl-context:
    //
    //   OpenGL, or rather the Win32 GDI integration of it, doesn't offer means
    //   to explicitly select the desired device. However the drivers of Nvidia
    //   and AMD offer a workaround to have programs select, that they prefer to
    //   execute on the discrete GPU rather than the CPU integrated one.
    //
    // These also appear to select the discrete "Arc" GPU on an Intel system,
    // and to influence the GPU selection on D3D11.
    __declspec(dllexport) uint32_t NvOptimusEnablement = 1;
    __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
#endif

// Call TestingWindow::Destroy if you want to delete the window singleton
TestingWindow* s_TestingWindow = nullptr;
TestingWindow::Backend TestingWindow::s_Backend = TestingWindow::Backend::null;
TestingWindow::Target TestingWindow::s_Target =
#if defined(__EMSCRIPTEN__)
    TestingWindow::Target::webbrowser;
#elif defined(RIVE_ANDROID)
    TestingWindow::Target::android;
#elif defined(RIVE_IOS_SIMULATOR)
    TestingWindow::Target::iossim;
#elif defined(RIVE_IOS)
    TestingWindow::Target::ios;
#else
    TestingWindow::Target::host;
#endif

const char* TestingWindow::BackendName(Backend backend)
{
    switch (backend)
    {
        case TestingWindow::Backend::gl:
            return "gl";
        case TestingWindow::Backend::d3d:
            return "d3d";
        case TestingWindow::Backend::d3d12:
            return "d3d12";
        case TestingWindow::Backend::metal:
            return "metal";
        case TestingWindow::Backend::vk:
            return "vk";
        case TestingWindow::Backend::moltenvk:
            return "moltenvk";
        case TestingWindow::Backend::swiftshader:
            return "swiftshader";
        case TestingWindow::Backend::angle:
            return "angle";
        case TestingWindow::Backend::dawn:
            return "dawn";
        case TestingWindow::Backend::wgpu:
            return "wgpu";
        case Backend::external:
            return "external";
        case TestingWindow::Backend::coregraphics:
            return "coregraphics";
        case TestingWindow::Backend::skia:
            return "skia";
        case TestingWindow::Backend::null:
            return "null";
        case TestingWindow::Backend::invalid:
            return "invalid";
    }
    RIVE_UNREACHABLE();
}

static std::vector<std::string> split(const char* str, char delimiter)
{
    std::stringstream ss(str);
    std::string token;
    std::vector<std::string> tokens;
    while (std::getline(ss, token, delimiter))
    {
        tokens.push_back(token);
    }
    return tokens;
}

TestingWindow::Backend TestingWindow::TryParseBackend(const char* name,
                                                      BackendParams* params)
{
    *params = {};
    // Backends can come in the form <backendName>, or
    // <gpuNameFilter>/<backendName>.
    std::vector<std::string> tokens = split(name, '/');
    assert(!tokens.empty());
    params->gpuNameFilter =
        tokens.size() > 1 ? tokens[tokens.size() - 2].c_str() : "";
    const std::string nameStr = tokens.back();
    const auto nameStartsWith = [&](std::string str) {
        return nameStr.rfind(str, 0) == 0;
    };
    const auto nameEndsWith = [&](std::string str) {
        auto result = nameStr.rfind(str);
        return result != std::string::npos &&
               result == nameStr.size() - str.size();
    };
    if (nameStartsWith("angle"))
    {
        if (nameStartsWith("anglemsaa"))
            params->msaa = true;
        if (nameEndsWith("_mtl") || nameEndsWith("_metal"))
            params->angleRenderer = ANGLERenderer::metal;
        else if (nameEndsWith("_d3d") || nameEndsWith("_d3d11"))
            params->angleRenderer = ANGLERenderer::d3d11;
        else if (nameEndsWith("_vk") || nameEndsWith("_vulkan"))
            params->angleRenderer = ANGLERenderer::vk;
        else if (nameEndsWith("_gles"))
            params->angleRenderer = ANGLERenderer::gles;
        else if (nameEndsWith("_gl"))
            params->angleRenderer = ANGLERenderer::gl;
        return Backend::angle;
    }
    if (nameStr == "gl")
    {
        return Backend::gl;
    }
    if (nameStr == "glatomic")
    {
        params->atomic = true;
        return Backend::gl;
    }
    if (nameStr == "glcw")
    {
        params->clockwise = true;
        return Backend::gl;
    }
    if (nameStr == "glmsaa")
    {
        params->msaa = true;
        return Backend::gl;
    }
    if (nameStr == "d3d")
    {
        return Backend::d3d;
    }
    if (nameStr == "d3datomic")
    {
        params->atomic = true;
        return Backend::d3d;
    }
    if (nameStr == "d3dmsaa")
    {
        params->msaa = true;
        return Backend::d3d;
    }
    if (nameStr == "d3d12")
    {
        return Backend::d3d12;
    }
    if (nameStr == "d3d12atomic")
    {
        params->atomic = true;
        return Backend::d3d12;
    }
    if (nameStr == "d3d12msaa")
    {
        params->msaa = true;
        return Backend::d3d12;
    }
    if (nameStr == "metal")
    {
        return Backend::metal;
    }
    if (nameStr == "metalcw")
    {
        params->clockwise = true;
        return Backend::metal;
    }
    if (nameStr == "metalatomic")
    {
        params->atomic = true;
        return Backend::metal;
    }
    if (nameStr == "metalmsaa")
    {
        params->msaa = true;
        return Backend::metal;
    }
    if (nameStr == "vulkan" || nameStr == "vk")
    {
        return Backend::vk;
    }
    if (nameStr == "vulkanatomic" || nameStr == "vkatomic")
    {
        params->atomic = true;
        return Backend::vk;
    }
    if (nameStr == "vulkanmsaa" || nameStr == "vkmsaa")
    {
        params->msaa = true;
        return Backend::vk;
    }
    if (nameStr == "vulkancore" || nameStr == "vkcore")
    {
        params->core = true;
        return Backend::vk;
    }
    if (nameStr == "vulkanmsaacore" || nameStr == "vkmsaacore")
    {
        params->core = true;
        params->msaa = true;
        return Backend::vk;
    }
    if (nameStr == "vulkansrgb" || nameStr == "vksrgb")
    {
        params->srgb = true;
        return Backend::vk;
    }
    if (nameStr == "vkcw")
    {
        params->clockwise = true;
        return Backend::vk;
    }
    if (nameStr == "vkcwatomic" || nameStr == "vkcwa")
    {
        params->clockwise = true;
        params->atomic = true;
        return Backend::vk;
    }
    if (nameStr == "moltenvk" || nameStr == "mvk")
    {
        return Backend::moltenvk;
    }
    if (nameStr == "moltenvkcore" || nameStr == "mvkcore")
    {
        params->core = true;
        return Backend::moltenvk;
    }
    if (nameStr == "swiftshader" || nameStr == "sw")
    {
        return Backend::swiftshader;
    }
    if (nameStr == "swiftshadercore" || nameStr == "swcore")
    {
        params->core = true;
        return Backend::swiftshader;
    }
    if (nameStr == "dawn")
    {
        return Backend::dawn;
    }
    if (nameStr == "dawnmsaa")
    {
        params->msaa = true;
        return Backend::dawn;
    }
    if (nameStr == "wgpu")
    {
        return Backend::wgpu;
    }
    if (nameStr == "wgpucw")
    {
        params->clockwise = true;
        return Backend::wgpu;
    }
    if (nameStr == "wgpumsaa")
    {
        params->msaa = true;
        return Backend::wgpu;
    }
    if (nameStr == "coregraphics")
    {
        return Backend::coregraphics;
    }
    if (nameStr == "skia")
    {
        return Backend::skia;
    }
    if (nameStr == "external")
    {
        return Backend::external;
    }
    if (nameStr == "null")
    {
        return Backend::null;
    }
    return Backend::invalid;
}

TestingWindow::Backend TestingWindow::ParseBackend(const char* name,
                                                   BackendParams* params)
{
    Backend backend = TryParseBackend(name, params);
    if (backend == Backend::invalid)
    {
        fprintf(stderr, "'%s': invalid TestingWindow::Backend\n", name);
        abort();
    }
    return backend;
}

static void set_environment_variable(const char* name, const char* value)
{
#ifndef PLATFORM_NO_ENV_API
    if (const char* existingValue = getenv(name))
    {
        printf("warning: %s=%s already set. Overriding with %s=%s\n",
               name,
               existingValue,
               name,
               value);
    }
#ifdef _WIN32
    SetEnvironmentVariableA(name, value);
#else
    setenv(name, value, /*overwrite=*/true);
#endif
#endif
}

TestingWindow* TestingWindow::Init(Backend backend,
                                   const BackendParams& backendParams,
                                   Visibility visibility,
                                   void* platformWindow)
{
    if (s_TestingWindow != nullptr)
    {
        s_Backend = backend;
        return s_TestingWindow;
    }

#if defined(_WIN32) && !defined(RIVE_UNREAL)
    // Set our backdoor GPU selection variables in case the API doesn't
    // allow us to select explicitly.
    const char* nameFilter = backendParams.gpuNameFilter.c_str();
    if (const char* gpuFromEnv = getenv("RIVE_GPU"); gpuFromEnv != nullptr)
    {
        // Override the program's GPU filter with one from the environment if
        // it's set.
        nameFilter = gpuFromEnv;
    }
    // "i" and "integrated" are special-case gpuNameFilters that mean "use
    // the integrated GPU".
    bool wantIntegratedGPU = static_cast<uint32_t>(
        strcmp(nameFilter, "integrated") == 0 || strcmp(nameFilter, "i") == 0);
    NvOptimusEnablement = !wantIntegratedGPU;
    AmdPowerXpressRequestHighPerformance = !wantIntegratedGPU;
#endif

    switch (backend)
    {
        case Backend::gl:
        case Backend::angle:
#ifndef RIVE_TOOLS_NO_GLFW
            if (backend != Backend::angle || visibility != Visibility::headless)
            {
                s_TestingWindow =
                    TestingWindow::MakeFiddleContext(backend,
                                                     backendParams,
                                                     visibility,
                                                     platformWindow);
            }
            else
#endif
            {
                s_TestingWindow =
                    MakeEGL(backend, backendParams, platformWindow);
            }
            break;
        case Backend::vk:
        case Backend::moltenvk:
        case Backend::swiftshader:
            if (backend == Backend::moltenvk)
            {
                // Use the MoltenVK built by
                // packages/runtime/renderer/make_moltenvk.sh
                constexpr static char kMoltenVKICD[] =
                    "../renderer/dependencies/MoltenVK/Package/Release/"
                    "MoltenVK/dynamic/dylib/macOS/MoltenVK_icd.json";
                set_environment_variable("VK_ICD_FILENAMES", kMoltenVKICD);
            }
            else if (backend == Backend::swiftshader)
            {
                // Use the swiftshader built by
                // packages/runtime/renderer/make_swiftshader.sh
                constexpr static char kSwiftShaderICD[] =
#ifdef __APPLE__
                    "../renderer/dependencies/SwiftShader/build/Darwin/"
                    "vk_swiftshader_icd.json";
#elif defined(_WIN32)
                    "../renderer/dependencies/SwiftShader/build/Windows/"
                    "vk_swiftshader_icd.json";
#else
                    "../renderer/dependencies/SwiftShader/build/Linux/"
                    "vk_swiftshader_icd.json";
#endif
                set_environment_variable("VK_ICD_FILENAMES", kSwiftShaderICD);
            }
#ifdef RIVE_ANDROID
            if (platformWindow != nullptr)
            {
                s_TestingWindow =
                    TestingWindow::MakeAndroidVulkan(backendParams,
                                                     platformWindow);
                break;
            }
#endif
            // Hook for platforms without rive_vk_bootstrap.
            if (auto* platformVulkanWindow =
                    TestingWindow::MakePlatformVulkan(backendParams))
            {
                s_TestingWindow = platformVulkanWindow;
                break;
            }
            if (visibility == Visibility::headless)
            {
                s_TestingWindow =
                    TestingWindow::MakeVulkanTexture(backendParams);
            }
            else
            {
                s_TestingWindow =
                    TestingWindow::MakeFiddleContext(backend,
                                                     backendParams,
                                                     visibility,
                                                     platformWindow);
            }
            break;
        case Backend::metal:
#if defined(__APPLE__) && !defined(RIVE_UNREAL)
            if (visibility == Visibility::headless)
            {
                s_TestingWindow =
                    TestingWindow::MakeMetalTexture(backendParams);
                break;
            }
#endif
            s_TestingWindow = TestingWindow::MakeFiddleContext(backend,
                                                               backendParams,
                                                               visibility,
                                                               platformWindow);
            break;
        case Backend::d3d:
        case Backend::d3d12:
        case Backend::dawn:
            s_TestingWindow = TestingWindow::MakeFiddleContext(backend,
                                                               backendParams,
                                                               visibility,
                                                               platformWindow);
            break;
        case Backend::wgpu:
            s_TestingWindow = TestingWindow::MakeWGPU(backendParams);
            break;
        case Backend::external:
            break;
        case Backend::coregraphics:
            s_TestingWindow = MakeCoreGraphics();
            break;
        case Backend::skia:
            s_TestingWindow = MakeSkia();
            break;
        case Backend::null:
            s_TestingWindow = MakeNULL();
            break;
        case Backend::invalid:
            break;
    }
    if (!s_TestingWindow)
    {
        fprintf(stderr,
                "Failed to create testing window for Backend::%s\n",
                BackendName(backend));
        abort();
    }

    s_Backend = backend;
    return s_TestingWindow;
}

TestingWindow* TestingWindow::Get()
{
    assert(s_TestingWindow); // Call Init() first!
    return s_TestingWindow;
}

void TestingWindow::Set(TestingWindow* inWindow)
{
    assert(inWindow);
    s_TestingWindow = inWindow;
}

void TestingWindow::Destroy()
{
    assert(s_TestingWindow);
    delete s_TestingWindow;
    s_TestingWindow = nullptr;
}

// Default no-op; platforms with their own impl define
// RIVE_PLATFORM_TESTING_WINDOW.
#ifndef RIVE_PLATFORM_TESTING_WINDOW
TestingWindow* TestingWindow::MakePlatformVulkan(const BackendParams&)
{
    return nullptr;
}
#endif
