/*
 * Copyright 2023 Rive
 */

#include "rive/artboard.hpp"
#include "rive/file.hpp"
#include "rive/refcnt.hpp"
#include "rive/layout.hpp"
#include "rive/animation/state_machine_instance.hpp"

#include <iterator>
#include <vector>

using namespace rive;

#ifdef RIVE_WEBGPU

#include "rive/renderer/rive_renderer.hpp"
#include "rive/renderer/webgpu/render_context_webgpu_impl.hpp"

#if RIVE_WEBGPU == 1
#include "../src/webgpu/webgpu_compat.h"
#endif
#include "marty.h"
#include "egg_v2.h"
#include "rope.h"

#include <webgpu/webgpu_cpp.h>
#include <emscripten.h>
#include <emscripten/html5.h>

using namespace rive::gpu;

static std::unique_ptr<RenderContext> renderContext;
static rcp<RenderTargetWebGPU> renderTarget;
static std::unique_ptr<Renderer> renderer;

static WGPUInstance instance;
static wgpu::Adapter adapter;
static wgpu::Device device;
static WGPUSurface surface;
static WGPUTextureFormat format = WGPUTextureFormat_Undefined;
static wgpu::Queue queue;

static rcp<File> rivFile;
static std::unique_ptr<ArtboardInstance> artboard;
static std::unique_ptr<Scene> scene;

extern "C" EM_BOOL animationFrame(double time, void* userData);
EM_JS(uint8_t, get_riv_buffer, (uint8_t** buffer, uint32_t* len), {
    if (!get_wagyu_buffer)
        return 0;
    const arrBuf = get_wagyu_buffer();
    if (!arrBuf)
        return 0;

    const arr = new Uint8Array(arrBuf), ptr = _malloc(arr.length);
    HEAPU8.set(arr, ptr);
    setValue(buffer, ptr, '*');
    setValue(len, arr.length, 'i32');
    return 1;
});

#if RIVE_WEBGPU > 1
void requestDeviceCallback(wgpu::RequestDeviceStatus status,
                           wgpu::Device deviceArg,
                           const char* message,
                           void* userdata)

#else
void requestDeviceCallback(WGPURequestDeviceStatus status,
                           WGPUDevice deviceArg,
                           const char* message,
                           void* userdata)
#endif
{
    assert(userdata == instance);

#if RIVE_WEBGPU > 1
    device = deviceArg;
#else
    device = wgpu::Device::Acquire(deviceArg);
#endif
    assert(device.Get());

    queue = device.GetQueue();
    assert(queue.Get());

    {
#if RIVE_WEBGPU > 1
        WGPUEmscriptenSurfaceSourceCanvasHTMLSelector htmlSelector =
            WGPU_EMSCRIPTEN_SURFACE_SOURCE_CANVAS_HTML_SELECTOR_INIT;
        htmlSelector.selector.data = "#canvas";
        htmlSelector.selector.length = 7;
#else
        WGPUSurfaceDescriptorFromCanvasHTMLSelector htmlSelector = {};
        htmlSelector.chain.sType =
            WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
        htmlSelector.selector = "#canvas";
#endif

        WGPUSurfaceDescriptor surfaceDesc = WGPU_SURFACE_DESCRIPTOR_INIT;
        surfaceDesc.nextInChain = (WGPUChainedStruct*)&htmlSelector;

        surface = wgpuInstanceCreateSurface(instance, &surfaceDesc);
        assert(surface);
    }

    {
#if RIVE_WEBGPU > 1
        WGPUSurfaceCapabilities capabilities = WGPU_SURFACE_CAPABILITIES_INIT;
        wgpuSurfaceGetCapabilities(surface, adapter.Get(), &capabilities);
        assert(capabilities.formatCount > 0);
        format = capabilities.formats[0];
        wgpuSurfaceCapabilitiesFreeMembers(capabilities);
#else
        format = wgpuSurfaceGetPreferredFormat(surface, adapter.Get());
#endif
        assert(format);
    }

    {
        WGPUSurfaceConfiguration conf = WGPU_SURFACE_CONFIGURATION_INIT;
        conf.device = device.Get();
        conf.format = format;

        wgpuSurfaceConfigure(surface, &conf);
    }

    RenderContextWebGPUImpl::ContextOptions contextOptions;
    renderContext = RenderContextWebGPUImpl::MakeContext(adapter,
                                                         device,
                                                         queue,
                                                         contextOptions);
    renderTarget =
        renderContext->static_impl_cast<RenderContextWebGPUImpl>()
            ->makeRenderTarget(static_cast<wgpu::TextureFormat>(format),
                               1920,
                               1080);
    renderer = std::make_unique<RiveRenderer>(renderContext.get());

    uint8_t* buffer;
    uint32_t buffer_len;
    if (get_riv_buffer(&buffer, &buffer_len))
    {
        rivFile = File::import({buffer, buffer_len}, renderContext.get());
        free(buffer);
    }
    if (!rivFile)
    {
        rivFile = File::import({marty, marty_len}, renderContext.get());
        // rivFile = File::import({egg_v2, egg_v2_len}, renderContext.get());
        // rivFile = File::import({rope, rope_len}, renderContext.get());
    }
    artboard = rivFile->artboardDefault();
    scene = artboard->defaultScene();
    scene->advanceAndApply(0);

    emscripten_set_canvas_element_size("#canvas", 1920, 1080);

    emscripten_request_animation_frame_loop(animationFrame, (void*)100);
}

#if RIVE_WEBGPU > 1
void requestAdapterCallback(WGPURequestAdapterStatus status,
                            WGPUAdapter adapterArg,
                            WGPUStringView message,
                            void* userdata,
                            void* /*userdata2*/)
#else
void requestAdapterCallback(WGPURequestAdapterStatus status,
                            WGPUAdapter adapterArg,
                            const char* message,
                            void* userdata)
#endif
{
    assert(adapterArg);
    assert(status == WGPURequestAdapterStatus_Success);
    assert(userdata == instance);
    adapter = wgpu::Adapter::Acquire(adapterArg);
#if RIVE_WEBGPU > 1
    adapter.RequestDevice({},
                          wgpu::CallbackMode::AllowSpontaneous,
                          requestDeviceCallback,
                          userdata);
#else
    adapter.RequestDevice({}, requestDeviceCallback, userdata);
#endif
}

static double lastTime = 0;
extern "C" EM_BOOL animationFrame(double time, void* userData)
{
    (void)time;
    (void)userData;

    WGPUSurfaceTexture surfaceTexture = WGPU_SURFACE_TEXTURE_INIT;

    wgpuSurfaceGetCurrentTexture(surface, &surfaceTexture);

    WGPUTexture texture = surfaceTexture.texture;

    WGPUTextureViewDescriptor textureViewDesc =
        WGPU_TEXTURE_VIEW_DESCRIPTOR_INIT;
    textureViewDesc.format = format;
    textureViewDesc.dimension = WGPUTextureViewDimension_2D;

    WGPUTextureView textureView =
        wgpuTextureCreateView(texture, &textureViewDesc);

    scene->advanceAndApply(lastTime == 0 ? 0 : (time - lastTime) * 1e-3f);
    lastTime = time;

    renderContext->beginFrame({
        .renderTargetWidth = renderTarget->width(),
        .renderTargetHeight = renderTarget->height(),
        .loadAction = gpu::LoadAction::clear,
        .clearColor = 0xff8030ff,
    });

    renderer->save();
    renderer->transform(computeAlignment(rive::Fit::contain,
                                         rive::Alignment::center,
                                         rive::AABB(0, 0, 1920, 1080),
                                         artboard->bounds()));
    scene->draw(renderer.get());
    renderer->restore();

    renderTarget->setTargetTextureView(textureView);
    renderContext->flush({.renderTarget = renderTarget.get()});

    wgpuTextureViewRelease(textureView);
    wgpuTextureRelease(texture);

    return EM_TRUE;
}

int main(void)
{
    instance = wgpuCreateInstance(NULL);
    assert(instance);

#if RIVE_WEBGPU > 1
    WGPURequestAdapterCallbackInfo requestAdapterCallbackInfo =
        WGPU_REQUEST_ADAPTER_CALLBACK_INFO_INIT;
    requestAdapterCallbackInfo.mode = WGPUCallbackMode_AllowSpontaneous;
    requestAdapterCallbackInfo.callback = requestAdapterCallback;
    requestAdapterCallbackInfo.userdata1 = instance;
    wgpuInstanceRequestAdapter(instance, NULL, requestAdapterCallbackInfo);
#else
    wgpuInstanceRequestAdapter(instance,
                               NULL,
                               requestAdapterCallback,
                               instance);
#endif

    return 0;
}

#endif

#ifdef RIVE_DAWN

#include "../path_fiddle/fiddle_context.hpp"

#include <dawn/webgpu_cpp.h>
#include <GLFW/glfw3.h>
#define GLFW_EXPOSE_NATIVE_WIN32
#include <GLFW/glfw3native.h>
#include <fstream>

static GLFWwindow* window = nullptr;
static std::unique_ptr<FiddleContext> fiddleContextDawn;

static void glfw_error_callback(int code, const char* message)
{
    printf("GLFW error: %i - %s\n", code, message);
}

int main(int argc, const char** argv)
{
    // Cause stdout and stderr to print immediately without buffering.
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);

    glfwSetErrorCallback(glfw_error_callback);

    if (!glfwInit())
    {
        fprintf(stderr, "Failed to initialize glfw.\n");
        return 1;
    }

    glfwWindowHint(GLFW_SAMPLES, 0);
    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_TRUE);
    glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_TRUE);
    glfwWindowHint(GLFW_FLOATING, GLFW_TRUE);
    window = glfwCreateWindow(1600, 1600, "Rive Renderer", nullptr, nullptr);
    if (!window)
    {
        glfwTerminate();
        fprintf(stderr, "Failed to create window.\n");
        return -1;
    }
    glfwSetWindowTitle(window, "Rive Renderer");

    std::unique_ptr<FiddleContext> fiddleContextDawn =
        FiddleContext::MakeDawnPLS({});

    int w, h;
    glfwGetFramebufferSize(window, &w, &h);
    fiddleContextDawn->onSizeChanged(window, w, h, 1);
    std::unique_ptr<Renderer> renderer = fiddleContextDawn->makeRenderer(w, h);

    const char* filename =
        argc > 1 ? argv[1] : "webgpu_player/rivs/poison_loader.riv";
    std::ifstream rivStream(filename, std::ios::binary);
    std::vector<uint8_t> rivBytes(std::istreambuf_iterator<char>(rivStream),
                                  {});
    rcp<File> rivFile = File::import(rivBytes, fiddleContextDawn->factory());
    std::unique_ptr<ArtboardInstance> artboard = rivFile->artboardDefault();
    std::unique_ptr<Scene> scene = artboard->defaultScene();
    scene->advanceAndApply(0);

    double lastTimestamp = 0;

    while (!glfwWindowShouldClose(window))
    {
        double timestamp = glfwGetTime();

        fiddleContextDawn->begin({
            .renderTargetWidth = static_cast<uint32_t>(w),
            .renderTargetHeight = static_cast<uint32_t>(h),
            .clearColor = 0xff8030ff,
        });

        renderer->save();
        renderer->transform(computeAlignment(rive::Fit::contain,
                                             rive::Alignment::center,
                                             rive::AABB(0, 0, w, h),
                                             artboard->bounds()));
        scene->draw(renderer.get());
        renderer->restore();

        fiddleContextDawn->end(window);
        fiddleContextDawn->tick();
        glfwPollEvents();

        if (lastTimestamp != 0)
        {
            scene->advanceAndApply(timestamp - lastTimestamp);
        }
        lastTimestamp = timestamp;
    }
    glfwTerminate();
    return 0;
}
#endif
