/*
 * Copyright 2024 Rive
 */

// Don't compile this file as part of the "tests" project.
#ifndef TESTING

#include <sstream>
#include "common/test_harness.hpp"
#include "common/testing_window.hpp"
#include "rive/artboard.hpp"
#include "rive/refcnt.hpp"
#include "rive/animation/state_machine_instance.hpp"
#include "rive/file.hpp"
#include "rive/text/font_hb.hpp"
#include "rive/text/raw_text.hpp"
#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"
#include "rive/lua/scripting_vm.hpp"
#include "rive/renderer/render_context.hpp"
#endif
#include "assets/roboto_flex.ttf.hpp"
#include <stdio.h>
#include <fstream>

#ifdef RIVE_ANDROID
#include "common/rive_android_app.hpp"
#endif

#ifdef __EMSCRIPTEN__
#include "common/rive_wasm_app.hpp"
#include <emscripten/emscripten.h>
#include <emscripten/html5.h>
#endif

static void update_parameter(int& val, int multiplier, char key, bool seenBang)
{
    if (seenBang)
        val = multiplier;
    else if (key >= 'a')
        val += multiplier;
    else
        val -= multiplier;
}

enum class InputMode : uint8_t
{
    chars,
    consolecommands
};

static int copiesLeft = 0;
static int copiesAbove = 0;
static int copiesRight = 0;
static int copiesBelow = 0;
static int rotations90 = 0;
static int zoomLevel = 0;
static int spacing = 0;
static int monitorIdx = 0;
static int paintStyle = 0;
static bool wireframe = false;
static bool paused = false;
static bool forceFixedDeltaTime = false;
static bool quit = false;
static InputMode inputMode = InputMode::chars;
static bool hotloadShaders = false;
static void key_pressed(char key)
{
    static int multiplier = 0;
    static bool seenDigit = false;
    static bool seenBang = false;
    if (key >= '0' && key <= '9')
    {
        multiplier = multiplier * 10 + (key - '0');
        seenDigit = true;
        return;
    }
    if (key == '!')
    {
        seenBang = true;
        return;
    }
    if (!seenDigit)
    {
        multiplier = seenBang ? 0 : 1;
    }
    switch (key)
    {
        case 'h':
        case 'H':
            update_parameter(copiesLeft, multiplier, key, seenBang);
            break;
        case 'k':
        case 'K':
            update_parameter(copiesAbove, multiplier, key, seenBang);
            break;
        case 'l':
        case 'L':
            update_parameter(copiesRight, multiplier, key, seenBang);
            break;
        case 'j':
        case 'J':
            update_parameter(copiesBelow, multiplier, key, seenBang);
            break;
        case 'x':
        case 'X':
            update_parameter(copiesLeft, multiplier, key, seenBang);
            update_parameter(copiesRight, multiplier, key, seenBang);
            break;
        case 'y':
        case 'Y':
            update_parameter(copiesAbove, multiplier, key, seenBang);
            update_parameter(copiesBelow, multiplier, key, seenBang);
            break;
        case 'r':
        case 'R':
            update_parameter(rotations90, multiplier, key, seenBang);
            break;
        case 'z':
        case 'Z':
            update_parameter(zoomLevel, multiplier, key, seenBang);
            break;
        case 's':
        case 'S':
            update_parameter(spacing, multiplier, key, seenBang);
            break;
        case 'm':
            monitorIdx += multiplier;
            break;
        case 'p':
            paintStyle = (paintStyle + multiplier) % 3;
            break;
        case 'P':
            paintStyle = (paintStyle + 3 - (multiplier % 3)) % 3;
            break;
        case 'w':
            wireframe = !wireframe;
            break;
        case 'u':
            paused = !paused;
            break;
        case 'f':
            forceFixedDeltaTime = !forceFixedDeltaTime;
            break;
        case 'q':
        case '\x03': // ^C
            quit = true;
            break;
        case '\x1b': // Esc
            break;
        case '`':
            hotloadShaders = true;
            break;
        case '~':
            if (inputMode == InputMode::chars)
            {
                inputMode = InputMode::consolecommands;
            }
            else
            {
                inputMode = InputMode::chars;
            }
            break;
        default:
            // fprintf(stderr, "invalid option: %c\n", key);
            // abort();
            break;
    }
    multiplier = 0;
    seenDigit = false;
    seenBang = false;
}

class Player
{
public:
    void init(std::string rivName, std::vector<uint8_t> rivBytes)
    {
        m_rivName = std::move(rivName);
        m_file = rive::File::import(rivBytes, TestingWindow::Get()->factory());
        assert(m_file);

#ifdef WITH_RIVE_SCRIPTING
        // Wire contexts before artboard instantiation; verify hooks may
        // call context:gpuCanvas() during construction.
        if (auto* vm = m_file->scriptingVM())
        {
            if (auto* sctx = vm->context())
            {
                sctx->setRenderContext(TestingWindow::Get()->renderContext());
            }
        }
#endif

        m_artboard = m_file->artboardDefault();
        assert(m_artboard);
        m_scene = m_artboard->defaultStateMachine();
        if (!m_scene)
        {
            m_scene = m_artboard->animationAt(0);
        }
        assert(m_scene);

        // Setup FPS.
        m_roboto = HBFont::Decode(assets::roboto_flex_ttf());
        m_blackStroke = TestingWindow::Get()->factory()->makeRenderPaint();
        m_blackStroke->color(0xff000000);
        m_blackStroke->style(rive::RenderPaintStyle::stroke);
        m_blackStroke->thickness(4);
        m_whiteFill = TestingWindow::Get()->factory()->makeRenderPaint();
        m_whiteFill->color(0xffffffff);
        m_timeLastFPSUpdate = std::chrono::high_resolution_clock::now();
        m_timestampPrevFrame = std::chrono::high_resolution_clock::now();
    }

    void doFrame()
    {
        if (quit || TestingWindow::Get()->shouldQuit()
#ifdef RIVE_ANDROID
            || !rive_android_app_poll_once()
#endif
        )
        {
            printf("\nShutting down\n");
            TestingWindow::Destroy(); // Exercise our PLS teardown process now
                                      // that we're done.
            TestHarness::Instance().shutdown();
#ifdef __EMSCRIPTEN__
            emscripten_cancel_main_loop();
            EM_ASM(if (window && window.close) window.close(););
#else
            exit(0);
#endif
            return;
        }

#ifdef __EMSCRIPTEN__
        {
            // Fit the canvas to the browser window size.
            int windowWidth = EM_ASM_INT(return window["innerWidth"]);
            int windowHeight = EM_ASM_INT(return window["innerHeight"]);
            double devicePixelRatio = emscripten_get_device_pixel_ratio();
            int canvasExpectedWidth = windowWidth * devicePixelRatio;
            int canvasExpectedHeight = windowHeight * devicePixelRatio;
            if (TestingWindow::Get()->width() != canvasExpectedWidth ||
                TestingWindow::Get()->height() != canvasExpectedHeight)
            {
                printf("Resizing HTML canvas to %i x %i.\n",
                       canvasExpectedWidth,
                       canvasExpectedHeight);
                TestingWindow::Get()->resize(canvasExpectedWidth,
                                             canvasExpectedHeight);
                emscripten_set_element_css_size("#canvas",
                                                windowWidth,
                                                windowHeight);
            }
        }
#endif

        std::chrono::time_point timeNow =
            std::chrono::high_resolution_clock::now();
        const double elapsedS =
            std::chrono::duration_cast<std::chrono::nanoseconds>(
                timeNow - m_timestampPrevFrame)
                .count() /
            1e9; // convert to s
        m_timestampPrevFrame = timeNow;

        float advanceDeltaTime = static_cast<float>(elapsedS);
        if (forceFixedDeltaTime)
        {
            advanceDeltaTime = 1.0f / 120;
        }

        // ORE auto-reopens its CB if a scripted shader re-enters during PLS
        // draw, so we only mark the primary frame here.
        TestingWindow::Get()->beginOreFrame();
        m_scene->advanceAndApply(paused ? 0 : advanceDeltaTime);
        m_artboard->drawCanvases();
        TestingWindow::Get()->endOreFrame();

        copiesLeft = std::max(copiesLeft, 0);
        copiesAbove = std::max(copiesAbove, 0);
        copiesRight = std::max(copiesRight, 0);
        copiesBelow = std::max(copiesBelow, 0);
        int copyCount =
            (copiesLeft + 1 + copiesRight) * (copiesAbove + 1 + copiesBelow);
        if (copyCount != lastReportedCopyCount ||
            paused != lastReportedPauseState)
        {
            printf("Drawing %i copies of %s%s at %u x %u\n",
                   copyCount,
                   m_rivName.c_str(),
                   paused ? " (paused)" : "",
                   TestingWindow::Get()->width(),
                   TestingWindow::Get()->height());
            lastReportedCopyCount = copyCount;
            lastReportedPauseState = paused;
        }

        auto renderer = TestingWindow::Get()->beginFrame({
            .clearColor = 0xff303030,
            .doClear = true,
            .wireframe = wireframe,
            .fillsDisabled = paintStyle == 2,
            .strokesDisabled = paintStyle == 1,
        });

        if (hotloadShaders)
        {
            hotloadShaders = false;
#ifndef RIVE_NO_STD_SYSTEM
            std::system("sh rebuild_shaders.sh /tmp/rive");
            TestingWindow::Get()->hotloadShaders();
#endif
        }

        renderer->save();

        uint32_t width = TestingWindow::Get()->width();
        uint32_t height = TestingWindow::Get()->height();
        for (int i = rotations90; (i & 3) != 0; --i)
        {
            renderer->transform(rive::Mat2D(0, 1, -1, 0, width, 0));
            std::swap(height, width);
        }
        if (zoomLevel != 0)
        {
            float scale = powf(1.25f, zoomLevel);
            renderer->translate(width / 2.f, height / 2.f);
            renderer->scale(scale, scale);
            renderer->translate(width / -2.f, height / -2.f);
        }

        // Draw the .riv.
        renderer->save();
        renderer->align(rive::Fit::contain,
                        rive::Alignment::center,
                        rive::AABB(0, 0, width, height),
                        m_artboard->bounds());
        float spacingPx = spacing * 5 + 150;
        renderer->translate(-spacingPx * copiesLeft, -spacingPx * copiesAbove);
        // drawInternal skips drawCanvases (we pre-passed above), matching
        // the Flutter widget's prepassCanvases + paint pattern.
        for (int y = -copiesAbove; y <= copiesBelow; ++y)
        {
            renderer->save();
            for (int x = -copiesLeft; x <= copiesRight; ++x)
            {
                m_artboard->drawInternal(renderer.get());
                renderer->translate(spacingPx, 0);
            }
            renderer->restore();
            renderer->translate(0, spacingPx);
        }
        renderer->restore();

        if (m_fpsText != nullptr)
        {
            // Draw FPS.
            renderer->save();
            renderer->translate(0, 20);
            m_fpsText->render(renderer.get(), m_blackStroke);
            m_fpsText->render(renderer.get(), m_whiteFill);
            renderer->restore();
        }

        renderer->restore();
        TestingWindow::Get()->endFrame();

        // Count FPS.
        ++m_fpsFrames;
        const double elapsedFPSUpdate =
            std::chrono::duration_cast<std::chrono::nanoseconds>(
                timeNow - m_timeLastFPSUpdate)
                .count() /
            1e9; // convert to s
        if (elapsedFPSUpdate >= 2.0)
        {
            double fps = m_fpsFrames / elapsedFPSUpdate;
            if (inputMode == InputMode::chars)
            {
                printf("[%.3f FPS]\n", fps);
            }

            char fpsRawText[32];
            snprintf(fpsRawText, sizeof(fpsRawText), "   %.1f FPS   ", fps);
            m_fpsText = std::make_unique<rive::RawText>(
                TestingWindow::Get()->factory());
            m_fpsText->maxWidth(width);
#ifdef RIVE_ANDROID
            m_fpsText->align(rive::TextAlign::center);
#else
            m_fpsText->align(rive::TextAlign::right);
#endif
            m_fpsText->sizing(rive::TextSizing::fixed);
            m_fpsText->append(fpsRawText, nullptr, m_roboto, 50.f);

            m_fpsFrames = 0;
            m_timeLastFPSUpdate = timeNow;
        }

        const rive::Mat2D alignmentMat =
            computeAlignment(rive::Fit::contain,
                             rive::Alignment::center,
                             rive::AABB(0, 0, width, height),
                             m_artboard->bounds());

        // Consume all input events until none are left in the queue
        TestingWindow::InputEventData inputEventData;
        while (TestingWindow::Get()->consumeInputEvent(inputEventData))
        {
            const rive::Vec2D mousePosAligned =
                alignmentMat.invertOrIdentity() *
                rive::Vec2D(inputEventData.metadata.posX,
                            inputEventData.metadata.posY);

            switch (inputEventData.eventType)
            {
                case TestingWindow::InputEvent::KeyPress:
                    key_pressed(inputEventData.metadata.key);
                    break;

                case TestingWindow::InputEvent::MouseMove:
                    m_scene->pointerMove(mousePosAligned);
                    break;

                case TestingWindow::InputEvent::MouseDown:
                    m_scene->pointerDown(mousePosAligned);
                    break;

                case TestingWindow::InputEvent::MouseUp:
                    m_scene->pointerUp(mousePosAligned);
                    break;
            }
        }

        std::string m_command;
        m_command.clear();
        char key;

        if (inputMode == InputMode::consolecommands)
        {
            while (TestHarness::Instance().peekChar(key))
            {
                m_command += key;
            }

            std::istringstream iss(m_command);
            std::string first, second;
            iss >> first >> second;
            if (first == "~")
            {
                inputMode = InputMode::chars;
            }
            else if (first == "fire")
            {
                if (!second.empty())
                {
                    if (auto* trigger = m_scene->getTrigger(second.c_str()))
                    {
                        trigger->fire();
                    }
                }
            }
        }
        else
        {
            while (TestHarness::Instance().peekChar(key))
            {
                key_pressed(key);
            }
        }
    }

private:
    std::string m_rivName;
    rive::rcp<rive::File> m_file;
    std::unique_ptr<rive::ArtboardInstance> m_artboard;
    std::unique_ptr<rive::Scene> m_scene;

    int lastReportedCopyCount = 0;
    bool lastReportedPauseState = paused;

    rive::rcp<rive::Font> m_roboto;
    rive::rcp<rive::RenderPaint> m_blackStroke;
    rive::rcp<rive::RenderPaint> m_whiteFill;
    std::unique_ptr<rive::RawText> m_fpsText;
    int m_fpsFrames = 0;
    std::chrono::high_resolution_clock::time_point m_timeLastFPSUpdate;
    std::chrono::high_resolution_clock::time_point m_timestampPrevFrame;
};

static Player player;

#if defined(RIVE_IOS) || defined(RIVE_IOS_SIMULATOR)
int player_ios_main(int argc, const char* argv[])
#elif defined(RIVE_ANDROID)
int rive_android_main(int argc, const char* const* argv)
#elif defined(__EMSCRIPTEN__)
int rive_wasm_main(int argc, const char* const* argv)
#elif defined(EXTERN_TOOLS)
int rive_main(int argc, const char* argv[])
#else
int main(int argc, const char* argv[])
#endif
{
#ifdef _WIN32
    // Cause stdout and stderr to print immediately without buffering.
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
#endif

    std::string rivName;
    std::vector<uint8_t> rivBytes;
    auto backend =
#ifdef __APPLE__
        TestingWindow::Backend::metal;
#else
        TestingWindow::Backend::vk;
#endif
    auto visibility = TestingWindow::Visibility::fullscreen;
    TestingWindow::BackendParams backendParams;
    bool onlyUbershaders = false;

    for (int i = 1; i < argc; ++i)
    {
        if (strcmp(argv[i], "--test_harness") == 0)
        {
            TestHarness::Instance().init(TCPClient::Connect(argv[++i]), 0);
            if (!TestHarness::Instance().fetchRivFile(rivName, rivBytes))
            {
                fprintf(stderr, "failed to fetch a riv file.");
                abort();
            }
        }
        else if (strcmp(argv[i], "--backend") == 0 ||
                 strcmp(argv[i], "-b") == 0)
        {
            backend = TestingWindow::ParseBackend(argv[++i], &backendParams);
        }
        else if (argv[i][0] == '-' &&
                 argv[i][1] == 'b') // "-bvk" without a space.
        {
            backend = TestingWindow::ParseBackend(argv[i] + 2, &backendParams);
        }
        else if (strcmp(argv[i], "--options") == 0 ||
                 strcmp(argv[i], "-k") == 0)
        {
            for (const char* k = argv[++i]; *k; ++k)
            {
                key_pressed(*k);
            }
        }
        else if (strcmp(argv[i], "--only_ubershaders") == 0 ||
                 strcmp(argv[i], "-u") == 0)
        {
            onlyUbershaders = true;
        }
        else if (argv[i][0] == '-' &&
                 argv[i][1] == 'k') // "-k1234asdf" without a space.
        {
            for (const char* k = argv[i] + 2; *k; ++k)
            {
                key_pressed(*k);
            }
        }
        else if (strcmp(argv[i], "--window") == 0 || strcmp(argv[i], "-w") == 0)
        {
            visibility = TestingWindow::Visibility::window;
        }
        else
        {
            // No argument name defaults to the source riv.
            if (strcmp(argv[i], "--src") == 0 || strcmp(argv[i], "-s") == 0)
            {
                ++i;
            }
            rivName = argv[i];
            std::ifstream rivStream(rivName, std::ios::binary);
            rivBytes =
                std::vector<uint8_t>(std::istreambuf_iterator<char>(rivStream),
                                     {});
        }
    }

    if (onlyUbershaders)
    {
        backendParams.shaderCompilationMode =
            rive::gpu::ShaderCompilationMode::onlyUbershaders;
    }

    TestingWindow::Init(backend,
                        backendParams,
                        visibility,
#ifdef RIVE_ANDROID
                        rive_android_app_wait_for_window()
#else
                        reinterpret_cast<void*>(
                            static_cast<intptr_t>(monitorIdx))
#endif
    );

    if (rivBytes.empty())
    {
        fprintf(stderr, "no .riv file specified");
        abort();
    }

    player.init(std::move(rivName), std::move(rivBytes));

#ifdef __EMSCRIPTEN__
    emscripten_set_main_loop([]() { player.doFrame(); }, 0, true);
#else
    for (;;)
    {
        player.doFrame();
    }
#endif

    return 0;
}

#endif
