/*
 * 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 isDepthStencil() const { return m_isDepthStencil; }

  virtual bool isPbuffer() const = 0;

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

protected:
  using BackendParams = TestingWindow::BackendParams;

  EGLWindow(
      EGLDisplay display,
      EGLConfig config,
      const BackendParams& backendParams)
      : m_display(display)
      , m_config(config)
      , m_isDepthStencil(backendParams.msaaSampleCount > 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_isDepthStencil;
  void* m_surface = nullptr;
  int m_width = 0;
  int m_height = 0;
};

class PbufferWindow : public EGLWindow
{
public:
  PbufferWindow(
      EGLDisplay display,
      EGLConfig config,
      const BackendParams& backendParams)
      : EGLWindow(display, config, backendParams)
  {
    resize(1, 1);
  }

  bool isPbuffer() 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,
      const BackendParams& backendParams,
      void* platformWindow)
      : EGLWindow(display, config, backendParams)
  {
    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 isPbuffer() 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();

#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();
      }
    }
    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();
    }

    // Android MSAA works by rendering offscreen (usually via
    // EXT_multisampled_render_to_texture). We only need depth/stencil on
    // the main framebuffer when using InterlockMode::depthStencil w/o MSAA.
    const bool needsDepthStencil = backendParams.msaaSampleCount == 1;

    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,
        needsDepthStencil ? 24 : 0,
        EGL_STENCIL_SIZE,
        needsDepthStencil ? 8 : 0,
        // Android MSAA works by rendering offscreen (usually via
        // EXT_multisampled_render_to_texture). Never request MSAA on the
        // main framebuffer.
        EGL_SAMPLE_BUFFERS,
        0,
        EGL_SAMPLES,
        0,
        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,
          backendParams,
          platformWindow);
    }
    else
    {
      m_window = std::make_unique<PbufferWindow>(
          m_Display,
          config,
          backendParams);
    }
    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->isDepthStencil() &&
                                    renderContextGLImpl()
                                        ->capabilities()
                                        .EXT_shader_pixel_local_storage &&
                                    m_window->isPbuffer();
    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;
  }

  FrameMode frameMode(const FrameOptions& options) const override
  {
    return m_renderer->frameMode(options);
  }

  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->isPbuffer())
    {
      // 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
