/*
 * Copyright 2022 Rive
 */

#include "testing_window.hpp"

#if defined(RIVE_TOOLS_NO_GL) || defined(__EMSCRIPTEN__)

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

#else

#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 "common/offscreen_render_target.hpp"
#include "rive/renderer/gl/render_context_gl_impl.hpp"
#include "rive/renderer/gl/render_target_gl.hpp"
#include "rive/renderer.hpp"
#include "rive/renderer/gl/render_target_gl.hpp"
#include "testing_gl_renderer.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 PFNEGLSWAPINTERVALPROC eglSwapInterval;
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(eglSwapInterval);
    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(const BackendParams& backendParams,
                     EGLint angleRenderer,
                     void* platformWindow) :
        m_renderer(TestingGLRenderer::Make(backendParams))
    {
        init_egl();

        // Use 1 sample and rely on EXT_multisampled_render_to_texture, which is
        // how android currently works.
        int samples = backendParams.msaa ? 1 : 0;

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

            const EGLint displayAttribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE,
                                             angleRenderer,
                                             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();
            }
            samples = 0; // Test our offscreen MSAA path on ANGLE.
        }
        else
#endif
        {
            assert(angleRenderer == 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 (angleRenderer != 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();
        }
        // Disable vsync -- we want to measure fps above 60.
        eglSwapInterval(m_Display, 0);

#ifdef RIVE_DESKTOP_GL
        // Load the OpenGL API using glad.
        if (!gladLoadCustomLoader(
                reinterpret_cast<GLADloadfunc>(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(m_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();
    }

    rive::rcp<rive_tests::OffscreenRenderTarget> makeOffscreenRenderTarget(
        uint32_t width,
        uint32_t height,
        bool riveRenderable) const override
    {
        return rive_tests::OffscreenRenderTarget::MakeGL(renderContextGLImpl(),
                                                         width,
                                                         height);
    }

    void flushPLSContext(
        rive::gpu::RenderTarget* offscreenRenderTarget) override
    {
        m_renderer->flushPLSContext(offscreenRenderTarget);
    }

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,
                                      const BackendParams& backendParams,
                                      void* platformWindow)
{
    EGLint angleRenderer = EGL_NONE;
    if (backend == Backend::angle)
    {
        switch (backendParams.angleRenderer)
        {
            case ANGLERenderer::metal:
                angleRenderer = EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE;
                break;
            case ANGLERenderer::d3d11:
                angleRenderer = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
                break;
            case ANGLERenderer::vk:
                angleRenderer = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
                break;
            case ANGLERenderer::gles:
                angleRenderer = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
                break;
            case ANGLERenderer::gl:
                angleRenderer = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
                break;
        }
    }
    return new TestingWindowEGL(backendParams, angleRenderer, platformWindow);
}

#endif
