/*
 * Copyright 2022 Rive
 */

#include "testing_window.hpp"

#ifdef RIVE_TOOLS_NO_GL

TestingWindow* TestingWindow::MakeEGL(Backend backend, void* platformWindow)
{
    return nullptr;
}

#else

#include "rive/renderer.hpp"
#include "testing_gl_renderer.hpp"
#include <cassert>
#include <stdio.h>

#define EGL_EGL_PROTOTYPES 0
#include <EGL/egl.h>
#include <EGL/eglext.h>

// Include after Windows headers due to conflicts with #defines.
#include "rive/renderer/gl/render_context_gl_impl.hpp"
#include "rive/renderer/gl/render_target_gl.hpp"

#if defined(_WIN32)

#include <libloaderapi.h>

using PlatformLibraryHandle = HMODULE;
using PlatformProcAddress = FARPROC;

static PlatformLibraryHandle platform_dlopen(const char* libname)
{
    PlatformLibraryHandle lib = LoadLibraryA(libname);
    if (!lib)
    {
        WCHAR err[512];
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
                          FORMAT_MESSAGE_IGNORE_INSERTS,
                      0,
                      GetLastError(),
                      0,
                      err,
                      512,
                      0);
        fprintf(stderr, "Failed load %s. %ws\n", libname, err);
    }
    return lib;
}

static PlatformProcAddress platform_dlsym(PlatformLibraryHandle lib,
                                          const char* symbol)
{

    return GetProcAddress(lib, symbol);
}

#else

#include <dlfcn.h>

using PlatformLibraryHandle = void*;
using PlatformProcAddress = void*;

static PlatformLibraryHandle platform_dlopen(const char* libname)
{
    std::string filename = libname;
#ifdef __APPLE__
    filename.append(".dylib");
#else
    filename.append(".so");
#endif
    PlatformLibraryHandle lib = dlopen(filename.c_str(), RTLD_LAZY);
    if (!lib)
    {
        fprintf(stderr, "Failed load %s. %s\n", filename.c_str(), dlerror());
    }
    return lib;
}

static PlatformProcAddress platform_dlsym(PlatformLibraryHandle lib,
                                          const char* symbol)
{
    return dlsym(lib, symbol);
}

#endif

static PlatformLibraryHandle s_LibEGL = nullptr;

#define GET_EGL_PROC(eglProc)                                                  \
    eglProc = (decltype(eglProc))platform_dlsym(s_LibEGL, #eglProc);           \
    if (!eglProc)                                                              \
    {                                                                          \
        fprintf(stderr, "Failed locate " #eglProc " in libEGL.\n");            \
        abort();                                                               \
    }

static PFNEGLGETDISPLAYPROC eglGetDisplay;
static PFNEGLQUERYSTRINGPROC eglQueryString;
static PFNEGLINITIALIZEPROC eglInitialize;
static PFNEGLCHOOSECONFIGPROC eglChooseConfig;
static PFNEGLCREATECONTEXTPROC eglCreateContext;
static PFNEGLDESTROYCONTEXTPROC eglDestroyContext;
static PFNEGLCREATEPBUFFERSURFACEPROC eglCreatePbufferSurface;
static PFNEGLCREATEWINDOWSURFACEPROC eglCreateWindowSurface;
static PFNEGLQUERYSURFACEPROC eglQuerySurface;
static PFNEGLDESTROYSURFACEPROC eglDestroySurface;
static PFNEGLMAKECURRENTPROC eglMakeCurrent;
static PFNEGLSWAPBUFFERSPROC eglSwapBuffers;
static PFNEGLGETPROCADDRESSPROC eglGetProcAddress;

static void init_egl()
{
    if (s_LibEGL)
    {
        return;
    }

    s_LibEGL = platform_dlopen("libEGL");
    if (!s_LibEGL)
    {
        fprintf(stderr,
                "Failed load libEGL. Did you build ANGLE and copy over libEGL "
                "and libGLESv2?\n");
        abort();
    }

    GET_EGL_PROC(eglGetDisplay);
    GET_EGL_PROC(eglQueryString);
    GET_EGL_PROC(eglInitialize);
    GET_EGL_PROC(eglChooseConfig);
    GET_EGL_PROC(eglCreateContext);
    GET_EGL_PROC(eglDestroyContext);
    GET_EGL_PROC(eglCreatePbufferSurface);
    GET_EGL_PROC(eglCreateWindowSurface);
    GET_EGL_PROC(eglQuerySurface);
    GET_EGL_PROC(eglDestroySurface);
    GET_EGL_PROC(eglMakeCurrent);
    GET_EGL_PROC(eglSwapBuffers);
    GET_EGL_PROC(eglGetProcAddress);
}

#ifdef DEBUG
static void GL_APIENTRY err_msg_callback(GLenum source,
                                         GLenum type,
                                         GLuint id,
                                         GLenum severity,
                                         GLsizei length,
                                         const GLchar* message,
                                         const void* userParam)
{
    if (type == GL_DEBUG_TYPE_ERROR_KHR)
    {
        printf("GL ERROR: %s\n", message);
        fflush(stdout);
        abort();
    }
    else if (type == GL_DEBUG_TYPE_PERFORMANCE_KHR)
    {
        // Don't display GL perf warnings during normal testing.
#if 0
        printf("GL PERF: %s\n", message);
#endif
    }
    else
    {
        printf("GL MISC: %s\n", message);
    }
}
#endif

// Use an offscreen, platform independent window.
class EGLWindow
{
public:
    virtual ~EGLWindow() { deleteSurface(); }

    operator EGLSurface() const { return m_surface; }
    int width() const { return m_width; }
    int height() const { return m_height; }
    bool isMSAA() const { return m_isMSAA; }

    virtual bool isOffscreen() const = 0;

    virtual bool resize(int width, int height) = 0;

protected:
    EGLWindow(EGLDisplay display, EGLConfig config, int samples) :
        m_display(display),
        m_config(config),
        // "samples == 1" means "msaa mode with 1 sample".
        // "samples == 0" means "non-msaa mode".
        m_isMSAA(samples > 0)
    {}

    void deleteSurface()
    {
        if (m_surface && !eglDestroySurface(m_display, m_surface))
        {
            fprintf(stderr, "eglDestroySurface failed.\n");
            abort();
        }
    }

    const EGLDisplay m_display;
    const EGLConfig m_config;
    const bool m_isMSAA;
    void* m_surface = nullptr;
    int m_width = 0;
    int m_height = 0;
};

class PbufferWindow : public EGLWindow
{
public:
    PbufferWindow(EGLDisplay display, EGLConfig config, int samples) :
        EGLWindow(display, config, samples)
    {
        resize(1, 1);
    }

    bool isOffscreen() const final { return true; }

    bool resize(int width, int height) final
    {
        deleteSurface();
        const EGLint surfaceAttribs[] = {EGL_WIDTH,
                                         width,
                                         EGL_HEIGHT,
                                         height,
                                         EGL_NONE};
        m_surface =
            eglCreatePbufferSurface(m_display, m_config, surfaceAttribs);
        if (!m_surface)
        {
            fprintf(stderr, "eglCreatePbufferSurface failed.\n");
            abort();
        }
        m_width = width;
        m_height = height;
        return true;
    }
};

class NativeWindow : public EGLWindow
{
public:
    NativeWindow(EGLDisplay display,
                 EGLConfig config,
                 int samples,
                 void* platformWindow) :
        EGLWindow(display, config, samples)
    {
        m_surface = eglCreateWindowSurface(
            m_display,
            m_config,
            reinterpret_cast<EGLNativeWindowType>(platformWindow),
            nullptr);
        if (!m_surface)
        {
            fprintf(stderr, "eglCreateWindowSurface failed.\n");
            abort();
        }
        EGLint eglInt;
        eglQuerySurface(m_display, m_surface, EGL_WIDTH, &eglInt);
        m_width = eglInt;
        eglQuerySurface(m_display, m_surface, EGL_HEIGHT, &eglInt);
        m_height = eglInt;
    }

    bool isOffscreen() const final { return false; }

    bool resize(int width, int height) final
    {
        return width <= m_width && height <= m_height;
    }
};

class TestingWindowEGL : public TestingWindow
{
public:
    TestingWindowEGL(EGLint angleBackend,
                     int samples,
                     std::unique_ptr<TestingGLRenderer> renderer,
                     void* platformWindow) :
        m_renderer(std::move(renderer))
    {
        init_egl();

#ifdef RIVE_DESKTOP_GL
        if (angleBackend != EGL_NONE)
        {
            PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
            GET_EGL_PROC(eglGetPlatformDisplayEXT);

            const EGLint displayAttribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE,
                                             angleBackend,
                                             EGL_NONE};
            m_Display = eglGetPlatformDisplayEXT(
                EGL_PLATFORM_ANGLE_ANGLE,
                reinterpret_cast<void*>(EGL_DEFAULT_DISPLAY),
                displayAttribs);
            if (!m_Display)
            {
                fprintf(stderr, "eglGetPlatformDisplayEXT failed.\n");
                abort();
            }
        }
        else
#endif
        {
            assert(angleBackend == EGL_NONE);
            m_Display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
            if (!m_Display)
            {
                fprintf(stderr, "eglGetDisplay failed.\n");
                abort();
            }
        }

        EGLint majorVersion;
        EGLint minorVersion;
        if (!eglInitialize(m_Display, &majorVersion, &minorVersion))
        {
            fprintf(stderr, "eglInitialize failed.\n");
            abort();
        }
        // printf("Initialized EGL version %i.%i\n", majorVersion,
        // minorVersion); printf("EGL_VENDOR: %s\n", eglQueryString(m_Display,
        // EGL_VENDOR)); printf("EGL_VERSION: %s\n", eglQueryString(m_Display,
        // EGL_VERSION));
        if (angleBackend != EGL_NONE &&
            !strstr(eglQueryString(m_Display, EGL_VERSION), "ANGLE"))
        {
            fprintf(stderr,
                    "libEGL does not appear to be ANGLE. Did you build ANGLE "
                    "and copy over libEGL "
                    "and libGLESv2?\n");
            abort();
        }

        EGLint numConfigs;
        const EGLint configAttribs[] = {EGL_SURFACE_TYPE,
                                        EGL_PBUFFER_BIT,
                                        EGL_RENDERABLE_TYPE,
                                        EGL_OPENGL_ES3_BIT,
                                        EGL_COLOR_BUFFER_TYPE,
                                        EGL_RGB_BUFFER,
                                        EGL_RED_SIZE,
                                        8,
                                        EGL_GREEN_SIZE,
                                        8,
                                        EGL_BLUE_SIZE,
                                        8,
                                        EGL_ALPHA_SIZE,
                                        8,
                                        EGL_DEPTH_SIZE,
                                        samples == 0 ? 0 : 24,
                                        EGL_STENCIL_SIZE,
                                        samples == 0 ? 0 : 8,
                                        EGL_SAMPLE_BUFFERS,
                                        samples == 0 ? 0 : 1,
                                        EGL_SAMPLES,
                                        samples,
                                        EGL_NONE};

        EGLConfig config;
        if (!eglChooseConfig(m_Display, configAttribs, &config, 1, &numConfigs))
        {
            fprintf(stderr, "eglChooseConfig failed.\n");
            abort();
        }

        // Create an ES 3.0 context. This very closely mirrors webgl2.
        const EGLint contextAttribs[] = {EGL_CONTEXT_MAJOR_VERSION,
                                         3,
                                         EGL_CONTEXT_MINOR_VERSION,
                                         0,
                                         EGL_NONE};
        m_Context =
            eglCreateContext(m_Display, config, nullptr, contextAttribs);
        if (m_Context == EGL_NO_CONTEXT)
        {
            fprintf(stderr, "eglCreateContext failed.\n");
            abort();
        }

        if (platformWindow != nullptr)
        {
            m_window = std::make_unique<NativeWindow>(m_Display,
                                                      config,
                                                      samples,
                                                      platformWindow);
        }
        else
        {
            m_window =
                std::make_unique<PbufferWindow>(m_Display, config, samples);
        }
        m_width = m_window->width();
        m_height = m_window->height();
        if (!eglMakeCurrent(m_Display, *m_window, *m_window, m_Context))
        {
            fprintf(stderr, "eglMakeCurrent failed.\n");
            abort();
        }

#ifdef RIVE_DESKTOP_GL
        // Load the OpenGL API using glad.
        if (!gladLoadCustomLoader((GLADloadproc)eglGetProcAddress))
        {
            fprintf(stderr, "Failed to initialize glad.\n");
            abort();
        }
#endif

        auto rendererStr =
            reinterpret_cast<const char*>(glGetString(GL_RENDERER));
        printf("==== EGL GPU: OpenGL %s; %s; %s ====\n",
               glGetString(GL_VENDOR),
               rendererStr,
               glGetString(GL_VERSION));

        int extensionCount;
        glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount);
#ifdef DEBUG
        for (int i = 0; i < extensionCount; ++i)
        {
            auto* ext =
                reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, i));
            if (strcmp(ext, "GL_KHR_debug") == 0 &&
                // Our shader compiles can take over 30 SECONDS on PowerVR when
                // debug output is enabled. Just don't use it.
                !strstr(rendererStr, "PowerVR"))
            {
                glEnable(GL_DEBUG_OUTPUT_KHR);
                glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);

                auto glDebugMessageControlKHR =
                    reinterpret_cast<PFNGLDEBUGMESSAGECONTROLKHRPROC>(
                        eglGetProcAddress("glDebugMessageControlKHR"));
                assert(glDebugMessageControlKHR);
                glDebugMessageControlKHR(GL_DONT_CARE,
                                         GL_DONT_CARE,
                                         GL_DONT_CARE,
                                         0,
                                         NULL,
                                         GL_TRUE);

                auto glDebugMessageCallbackKHR =
                    reinterpret_cast<PFNGLDEBUGMESSAGECALLBACKKHRPROC>(
                        eglGetProcAddress("glDebugMessageCallbackKHR"));
                assert(glDebugMessageCallbackKHR);
                glDebugMessageCallbackKHR(&err_msg_callback, nullptr);

                // printf("%s enabled.\n", ext);
                continue;
            }
        }
#endif

        m_renderer->init(reinterpret_cast<void*>(eglGetProcAddress));
    }

    ~TestingWindowEGL()
    {
        eglMakeCurrent(EGL_NO_DISPLAY,
                       EGL_NO_SURFACE,
                       EGL_NO_SURFACE,
                       EGL_NO_CONTEXT);
        if (m_Context)
        {
            eglDestroyContext(m_Display, m_Context);
        }
    }

    rive::Factory* factory() override { return m_renderer->factory(); }

    void resize(int width, int height) override
    {
        if (width == m_width && height == m_height)
        {
            return;
        }

        // EXT_shader_pixel_local_storage has issues rendering to an offscreen
        // Pbuffer.
        bool needsOffscreenWorkaround = !m_window->isMSAA() &&
                                        renderContextGLImpl()
                                            ->capabilities()
                                            .EXT_shader_pixel_local_storage &&
                                        m_window->isOffscreen();
        if (needsOffscreenWorkaround || !m_window->resize(width, height))
        {
            // ARM Mali GPUs seem to hang while rendering goldens to a Pbuffer
            // with EXT_shader_pixel_local_storage. Rendering to a texture
            // instead seems to work.
            m_headlessRenderTexture = glutils::Texture();
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, m_headlessRenderTexture);
            glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
        }
        else
        {
            m_headlessRenderTexture = glutils::Texture::Zero();
            if (!eglMakeCurrent(m_Display, *m_window, *m_window, m_Context))
            {
                fprintf(stderr, "eglMakeCurrent failed.\n");
                abort();
            }
        }

        glViewport(0, 0, width, height);
        m_width = width;
        m_height = height;
    }

    std::unique_ptr<rive::Renderer> beginFrame(
        const FrameOptions& options) override
    {
        auto renderer =
            m_renderer->reset(m_width, m_height, m_headlessRenderTexture);
        m_renderer->beginFrame(options);
        return renderer;
    }

    void endFrame(std::vector<uint8_t>* pixelData) override
    {
        m_renderer->flush();
        if (m_headlessRenderTexture != 0 && !m_window->isOffscreen())
        {
            // Copy the offscreen texture back to the main window for
            // visualization purposes.
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
            glBlitFramebuffer(0,
                              0,
                              m_width,
                              m_height,
                              0,
                              0,
                              m_width,
                              m_height,
                              GL_COLOR_BUFFER_BIT,
                              GL_NEAREST);
        }
        if (pixelData)
        {
            pixelData->resize(m_height * m_width * 4);
            static_cast<rive::gpu::RenderTargetGL*>(m_renderer->renderTarget())
                ->bindDestinationFramebuffer(GL_READ_FRAMEBUFFER);
            glReadPixels(0,
                         0,
                         m_width,
                         m_height,
                         GL_RGBA,
                         GL_UNSIGNED_BYTE,
                         pixelData->data());
        }
        eglSwapBuffers(m_Display, *m_window);
    }

    rive::gpu::RenderContext* renderContext() const override
    {
        return m_renderer->renderContext();
    }

    rive::gpu::RenderContextGLImpl* renderContextGLImpl() const override
    {
        if (auto ctx = renderContext())
        {
            return ctx->static_impl_cast<rive::gpu::RenderContextGLImpl>();
        }
        return nullptr;
    }

    rive::gpu::RenderTarget* renderTarget() const override
    {
        return m_renderer->renderTarget();
    }

    void flushPLSContext() override { m_renderer->flushPLSContext(); }

private:
    const std::unique_ptr<TestingGLRenderer> m_renderer;
    void* m_Display;
    void* m_Context;
    std::unique_ptr<EGLWindow> m_window;
    glutils::Texture m_headlessRenderTexture = glutils::Texture::Zero();
};

TestingWindow* TestingWindow::MakeEGL(Backend backend, void* platformWindow)
{
    auto rendererFlags = RendererFlags::none;
    EGLint angleBackend = EGL_NONE;
    int samples = 0;
    switch (backend)
    {
        case Backend::glatomic:
        case Backend::glcw:
            rendererFlags |= RendererFlags::disableRasterOrdering;
            break;
        case Backend::glmsaa:
            rendererFlags |= RendererFlags::useMSAA;
#ifdef RIVE_ANDROID
            samples = 0; // Test EXT_multisampled_render_to_texture on Android.
#else
            samples = 4;
#endif
            break;
        case Backend::gl:
            break;
        case Backend::anglemsaa:
            rendererFlags |= RendererFlags::useMSAA;
            samples = 0; // Test our offscreen MSAA path on ANGLE.
        case Backend::angle:
#ifdef __APPLE__
            angleBackend = EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE;
#elif defined(_WIN32)
            angleBackend = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
#else
            angleBackend = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
#endif
            break;
        case Backend::d3d:
        case Backend::d3datomic:
        case Backend::metal:
        case Backend::metalcw:
        case Backend::metalatomic:
        case Backend::vk:
        case Backend::vkcore:
        case Backend::vkcw:
        case Backend::moltenvk:
        case Backend::moltenvkcore:
        case Backend::swiftshader:
        case Backend::swiftshadercore:
        case Backend::dawn:
        case Backend::rhi:
        case Backend::coregraphics:
        case Backend::skia:
            printf("Invalid backend for TestingWindow::MakeEGLPbuffer.");
            abort();
            break;
    }
    if (IsClockwiseFill(backend))
    {
        rendererFlags |= RendererFlags::clockwiseFillOverride;
    }
    return new TestingWindowEGL(angleBackend,
                                samples,
                                TestingGLRenderer::Make(rendererFlags),
                                platformWindow);
}

#endif
