/*
 * Copyright 2022 Rive
 */

#include "rive/renderer/gl/gl_utils.hpp"
#include "rive/rive_types.hpp"
#include "rive/shapes/paint/image_sampler.hpp"

#include <stdio.h>
#include <sstream>
#include <thread>
#include <vector>

#include "generated/shaders/glsl.glsl.hpp"

#ifdef RIVE_GL_NAMES_ARE_PER_CONTEXT
#include <atomic>
#include <mutex>
#include <unordered_map>
#include <emscripten/html5.h>
#endif

#ifdef BYPASS_EMSCRIPTEN_SHADER_PARSER
#include <emscripten/emscripten.h>
#include <emscripten/html5.h>

// Emscripten's shader preprocessor crashes on PLS shaders. This method allows
// us to bypass Emscripten and set a WebGL shader source directly.
EM_JS(void,
      webgl_shader_source,
      (EMSCRIPTEN_WEBGL_CONTEXT_HANDLE gl, GLuint shader, const char* source),
      {
          gl = GL.getContext(gl).GLctx;
          shader = GL.shaders[shader];
          source = UTF8ToString(source);
          gl.shaderSource(shader, source);
      });
#endif

namespace glutils
{
static void delete_name(GLObjectType type, GLuint id)
{
    switch (type)
    {
        case GLObjectType::buffer:
            glDeleteBuffers(1, &id);
            return;
        case GLObjectType::texture:
            glDeleteTextures(1, &id);
            return;
        case GLObjectType::framebuffer:
            glDeleteFramebuffers(1, &id);
            return;
        case GLObjectType::renderbuffer:
            glDeleteRenderbuffers(1, &id);
            return;
        case GLObjectType::vertexArray:
            glDeleteVertexArrays(1, &id);
            return;
        case GLObjectType::shader:
            glDeleteShader(id);
            return;
        case GLObjectType::program:
            glDeleteProgram(id);
            return;
    }
    RIVE_UNREACHABLE();
}

#ifdef RIVE_GL_NAMES_ARE_PER_CONTEXT
namespace
{
struct AbandonedName
{
    GLObjectType type;
    GLuint id;
};

std::mutex g_abandonedMutex;
std::unordered_map<GLContextID, std::vector<AbandonedName>> g_abandonedNames;
std::atomic<uint32_t> g_abandonedCount{0};
std::atomic<uint32_t> g_reclaimedCount{0};
} // namespace

GLContextID CurrentContextID()
{
    return static_cast<GLContextID>(emscripten_webgl_get_current_context());
}

static void abandon_name(GLObjectType type, GLuint id, GLContextID owner)
{
    {
        std::lock_guard<std::mutex> lock(g_abandonedMutex);
        g_abandonedNames[owner].push_back({type, id});
    }
    g_abandonedCount.fetch_add(1, std::memory_order_relaxed);
}

void ReclaimAbandonedNames()
{
    if (g_abandonedCount.load(std::memory_order_acquire) ==
        g_reclaimedCount.load(std::memory_order_relaxed))
    {
        return;
    }
    std::vector<AbandonedName> mine;
    {
        std::lock_guard<std::mutex> lock(g_abandonedMutex);
        auto it = g_abandonedNames.find(CurrentContextID());
        if (it == g_abandonedNames.end())
        {
            return;
        }
        mine.swap(it->second);
        g_abandonedNames.erase(it);
    }
    for (const AbandonedName& name : mine)
    {
        delete_name(name.type, name.id);
    }
    g_reclaimedCount.fetch_add(static_cast<uint32_t>(mine.size()),
                               std::memory_order_release);
}

uint32_t AbandonedNameCount()
{
    return g_abandonedCount.load(std::memory_order_relaxed);
}

uint32_t ReclaimedNameCount()
{
    return g_reclaimedCount.load(std::memory_order_relaxed);
}
#endif

void GLObject::destroy(GLObjectType type)
{
    if (m_id == 0)
    {
        return;
    }
#ifdef RIVE_GL_NAMES_ARE_PER_CONTEXT
    if (m_context != CurrentContextID())
    {
        abandon_name(type, m_id, m_context);
        m_id = 0;
        return;
    }
#endif
    delete_name(type, m_id);
    m_id = 0;
}

void GLObject::adopt(GLObjectType type, GLObject&& rhs)
{
    destroy(type);
    m_id = std::exchange(rhs.m_id, 0);
#ifdef RIVE_GL_NAMES_ARE_PER_CONTEXT
    m_context = rhs.m_context;
#endif
}

void GLObject::adoptName(GLObjectType type, GLuint adoptedID)
{
    destroy(type);
    m_id = adoptedID;
#ifdef RIVE_GL_NAMES_ARE_PER_CONTEXT
    m_context = CurrentContextID();
#endif
}

void CompileAndAttachShader(GLuint program,
                            GLenum type,
                            const char* source,
                            const GLCapabilities& capabilities,
                            DebugPrintErrorAndAbort debugPrintErrornAndAbort)
{
    CompileAndAttachShader(program,
                           type,
                           nullptr,
                           0,
                           &source,
                           1,
                           capabilities,
                           debugPrintErrornAndAbort);
}

void CompileAndAttachShader(GLuint program,
                            GLenum type,
                            const char* defines[],
                            size_t numDefines,
                            const char* inputSources[],
                            size_t numInputSources,
                            const GLCapabilities& capabilities,
                            DebugPrintErrorAndAbort debugPrintErrornAndAbort)
{
    GLuint shader = CompileShader(type,
                                  defines,
                                  numDefines,
                                  inputSources,
                                  numInputSources,
                                  capabilities,
                                  debugPrintErrornAndAbort);
    glAttachShader(program, shader);
    glDeleteShader(shader);
}

GLuint CompileShader(GLuint type,
                     const char* source,
                     const GLCapabilities& capabilities,
                     DebugPrintErrorAndAbort debugPrintErrornAndAbort)
{
    return CompileShader(type,
                         nullptr,
                         0,
                         &source,
                         1,
                         capabilities,
                         debugPrintErrornAndAbort);
}

GLuint CompileShader(GLuint type,
                     const char* defines[],
                     size_t numDefines,
                     const char* inputSources[],
                     size_t numInputSources,
                     const GLCapabilities& capabilities,
                     DebugPrintErrorAndAbort debugPrintErrornAndAbort)
{
    std::ostringstream shaderSource;
    shaderSource << "#version " << capabilities.contextVersionMajor
                 << capabilities.contextVersionMinor << '0';
    if (capabilities.isGLES)
    {
        shaderSource << " es";
    }
    shaderSource << '\n';
    // Create our own "GLSL_VERSION" macro. In "#version 320 es", Qualcomm
    // incorrectly substitutes
    // __VERSION__ to 300.
    shaderSource << "#define " << GLSL_GLSL_VERSION << ' '
                 << capabilities.contextVersionMajor
                 << capabilities.contextVersionMinor << "0\n";
    if (type == GL_VERTEX_SHADER)
    {
        shaderSource << "#define " << GLSL_VERTEX "\n";
    }
    else if (GL_FRAGMENT_SHADER)
    {
        shaderSource << "#define " << GLSL_FRAGMENT "\n";
    }
    for (size_t i = 0; i < numDefines; ++i)
    {
        shaderSource << "#define " << defines[i] << " true\n";
    }
    if (!capabilities.ANGLE_base_vertex_base_instance_shader_builtin)
    {
        shaderSource << "#define " << GLSL_BASE_INSTANCE_UNIFORM_NAME << ' '
                     << BASE_INSTANCE_UNIFORM_NAME << '\n';
    }
    if (capabilities.needsFloatingPointTessellationTexture)
    {
        shaderSource << "#define " << GLSL_TESS_TEXTURE_FLOATING_POINT << '\n';
    }
    if (capabilities.isMali)
    {
        shaderSource << "#define " << GLSL_GL_RENDERER_MALI << '\n';
    }
    shaderSource << rive::gpu::glsl::glsl << "\n";
    for (size_t i = 0; i < numInputSources; ++i)
    {
        shaderSource << inputSources[i] << "\n";
    }
    return CompileRawGLSL(type,
                          shaderSource.str().c_str(),
                          debugPrintErrornAndAbort);
}

#ifdef DEBUG
void PrintShaderCompilationErrors(GLuint shader)
{
    GLint maxLength = 0;
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
    std::vector<GLchar> infoLog(maxLength);
    glGetShaderInfoLog(shader, maxLength, &maxLength, &infoLog[0]);
    fprintf(stderr, "Failed to compile shader\n");
    // Print the error message *before* the shader in case stderr hasn't
    // finished flushing when we call abort() further on.
    fprintf(stderr, "%s\n", &infoLog[0]);

    GLint sourceLength = 0;
    glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength);
    std::vector<GLchar> shaderSource(sourceLength);
    glGetShaderSource(shader, sourceLength, nullptr, shaderSource.data());
    int l = 1;
    std::stringstream stream(shaderSource.data());
    std::string lineStr;
    while (std::getline(stream, lineStr, '\n'))
    {
        fprintf(stderr, "%4i| %s\n", l++, lineStr.c_str());
    }
    // Print the error message, again, *after* the shader where it's easier
    // to find in the console.
    fprintf(stderr, "%s\n", &infoLog[0]);
    fflush(stderr);
}
#endif

[[nodiscard]] GLuint CompileRawGLSL(
    GLenum shaderType,
    const char* rawGLSL,
    DebugPrintErrorAndAbort debugPrintErrornAndAbort)
{
    GLuint shader = glCreateShader(shaderType);
#ifdef BYPASS_EMSCRIPTEN_SHADER_PARSER
    // Emscripten's shader preprocessor crashes on PLS shaders. Feed Emscripten
    // something very simple and then hop to WebGL to bypass it and set the real
    // shader source.
    const char* kMinimalShader =
        shaderType == GL_VERTEX_SHADER
            ? "#version 300 es\nvoid main() { gl_Position = vec4(0); }"
            : "#version 300 es\nvoid main() {}";
    glShaderSource(shader, 1, &kMinimalShader, nullptr);
    webgl_shader_source(emscripten_webgl_get_current_context(),
                        shader,
                        rawGLSL);
#else
    glShaderSource(shader, 1, &rawGLSL, nullptr);
#endif
    glCompileShader(shader);
#ifdef DEBUG
    if (debugPrintErrornAndAbort == DebugPrintErrorAndAbort::yes)
    {
        GLint isCompiled = 0;
        glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
        if (isCompiled == GL_FALSE)
        {
            PrintShaderCompilationErrors(shader);
            glDeleteShader(shader);
            // Give stderr another second to finish flushing before we abort.
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            abort();
        }
    }
#else
    std::ignore = debugPrintErrornAndAbort;
#endif
    return shader;
}

#ifdef DEBUG
void PrintLinkProgramErrors(GLuint program)
{
    GLint maxLength = 0;
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
    std::vector<GLchar> infoLog(maxLength);
    glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
    fprintf(stderr, "Failed to link program %s\n", &infoLog[0]);
    fflush(stderr);
}
#endif

void LinkProgram(GLuint program,
                 DebugPrintErrorAndAbort debugPrintErrornAndAbort)
{
    glLinkProgram(program);
#ifdef DEBUG
    if (debugPrintErrornAndAbort == DebugPrintErrorAndAbort::yes)
    {
        GLint isLinked = 0;
        glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
        if (isLinked == GL_FALSE)
        {
            PrintLinkProgramErrors(program);
            abort();
        }
    }
#else
    std::ignore = debugPrintErrornAndAbort;
#endif
}

void Program::compileAndAttachShader(GLuint type,
                                     const char* defines[],
                                     size_t numDefines,
                                     const char* sources[],
                                     size_t numSources,
                                     const GLCapabilities& capabilities)
{
    assert(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER);
    glutils::Shader& internalShader =
        type == GL_VERTEX_SHADER ? m_vertexShader : m_fragmentShader;
    internalShader
        .compile(type, defines, numDefines, sources, numSources, capabilities);
    glAttachShader(m_id, internalShader);
}

void Shader::compile(GLenum type,
                     const char* defines[],
                     size_t numDefines,
                     const char* sources[],
                     size_t numSources,
                     const GLCapabilities& capabilities)
{
    reset(CompileShader(type,
                        defines,
                        numDefines,
                        sources,
                        numSources,
                        capabilities));
}

void SetTexture2DSamplingParams(GLenum minFilter, GLenum magFilter)
{
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

GLint gl_wrap_from_image_wrap(rive::ImageWrap wrap)
{
    switch (wrap)
    {
        case rive::ImageWrap::clamp:
            return GL_CLAMP_TO_EDGE;
        case rive::ImageWrap::repeat:
            return GL_REPEAT;
        case rive::ImageWrap::mirror:
            return GL_MIRRORED_REPEAT;
    }

    RIVE_UNREACHABLE();
}

GLint gl_min_filter_for_image_filter(rive::ImageFilter filter)
{
    switch (filter)
    {
        case rive::ImageFilter::bilinear:
            return GL_LINEAR_MIPMAP_NEAREST;
        case rive::ImageFilter::nearest:
            return GL_NEAREST;
    }

    RIVE_UNREACHABLE();
}

GLint gl_mag_filter_for_image_filter(rive::ImageFilter filter)
{
    switch (filter)
    {
        case rive::ImageFilter::nearest:
            return GL_NEAREST;
        case rive::ImageFilter::bilinear:
            return GL_LINEAR;
    }

    RIVE_UNREACHABLE();
}

void SetTexture2DSamplingParams(rive::ImageSampler samplingParams)
{
    glTexParameteri(GL_TEXTURE_2D,
                    GL_TEXTURE_MIN_FILTER,
                    gl_min_filter_for_image_filter(samplingParams.filter));
    glTexParameteri(GL_TEXTURE_2D,
                    GL_TEXTURE_MAG_FILTER,
                    gl_mag_filter_for_image_filter(samplingParams.filter));
    glTexParameteri(GL_TEXTURE_2D,
                    GL_TEXTURE_WRAP_S,
                    gl_wrap_from_image_wrap(samplingParams.wrapX));
    glTexParameteri(GL_TEXTURE_2D,
                    GL_TEXTURE_WRAP_T,
                    gl_wrap_from_image_wrap(samplingParams.wrapY));
}

void BlitFramebuffer(rive::IAABB bounds,
                     uint32_t renderTargetHeight,
                     GLbitfield mask)
{
    // glBlitFramebuffer is oriented bottom-up.
    uint32_t l = bounds.left;
    uint32_t b = renderTargetHeight - bounds.bottom;
    uint32_t r = bounds.right;
    uint32_t t = renderTargetHeight - bounds.top;
    glBlitFramebuffer(l, b, r, t, l, b, r, t, mask, GL_NEAREST);
}

void Uniform1iByName(GLuint programID, const char* name, GLint value)
{
    GLint location = glGetUniformLocation(programID, name);
    // Don't allow non-existent uniforms. glUniform1i() is supposed to silently
    // ignore -1, but Moto G7 Play throws an error. We also just shouldn't be
    // querying uniform locations we know aren't going to exist anyway for
    // performance reasons.
    assert(location != -1);
    glUniform1i(location, value);
}
} // namespace glutils
