/*
 * 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;
        }

        m_scene->advanceAndApply(paused ? 0 : advanceDeltaTime);

        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);
        for (int y = -copiesAbove; y <= copiesBelow; ++y)
        {
            renderer->save();
            for (int x = -copiesLeft; x <= copiesRight; ++x)
            {
                // drawInternal skips drawCanvases. In the future we can
                // pre-pass them, but ORE commandBuffers are currently wired up
                // in a way that causes severe perf regressions and flickering
                // on Vulkan. Once deferred rendering is finished we can turn
                // pre-passes back on.
                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
