/*
 * Copyright 2024 Rive
 */

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

#include "player.hpp"

#include <optional>
#include <sstream>
#include "common/test_harness.hpp"
#include "common/testing_window.hpp"
#include "rive/animation/state_machine_instance.hpp"
#include "rive/artboard.hpp"
#include "rive/file.hpp"
#include "rive/input/gamepad_batch.hpp"
#include "rive/renderer.hpp"
#include "rive/renderer/scoped_autorelease_pool.hpp"
#include "rive/scene.hpp"
#include "rive/text/font_hb.hpp"
#include "rive/text/raw_text.hpp"
#include "rive/viewmodel/viewmodel_instance.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
#ifdef RIVE_CANVAS
#include "common/testing_window_sink.hpp"
#include "rive/renderer/cmd/deferred_session.hpp"
#endif
#include "assets/roboto_flex.ttf.hpp"
#include <stdio.h>
#include <condition_variable>
#include <fstream>
#include <mutex>
#include <optional>
#include <thread>

#if defined(RIVE_ANDROID) && !defined(RIVE_UNREAL)
#include "common/rive_android_app.hpp"
#endif

#if (defined(RIVE_IOS) || defined(RIVE_IOS_SIMULATOR)) && !defined(RIVE_UNREAL)
#include "common/rive_ios_app.hpp"
#endif

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

// The FPS readout drawn over the .riv, and the resources it needs.
struct Player::FPSOverlay
{
    rive::rcp<rive::Font> roboto;
    rive::rcp<rive::RenderPaint> blackStroke;
    rive::rcp<rive::RenderPaint> whiteFill;
    std::unique_ptr<rive::RawText> text;
    int frames = 0;
    std::chrono::high_resolution_clock::time_point timeLastUpdate;
};

struct Player::FrameJob
{
    TestingWindow::FrameOptions options;
#ifdef RIVE_CANVAS
    rive::cmd::DeferredFrame frame;
#endif
    std::vector<uint8_t>* pixels = nullptr;
};

// One frame in flight at most: submit blocks until the previous frame has
// presented. Every window call happens on this thread while it lives.
struct Player::RenderThread
{
    explicit RenderThread(Player* player) :
        m_thread([this, player] { run(player); })
    {}

    ~RenderThread()
    {
        {
            std::lock_guard lock(m_mutex);
            m_quit = true;
        }
        m_cv.notify_all();
        m_thread.join();
    }

    void submit(FrameJob job)
    {
        std::unique_lock lock(m_mutex);
        m_cv.wait(lock, [this] { return idle(); });
        m_pending = std::move(job);
        m_cv.notify_all();
    }

    // Returns once every submitted frame has presented.
    void drain()
    {
        std::unique_lock lock(m_mutex);
        m_cv.wait(lock, [this] { return idle(); });
    }

private:
    bool idle() const { return !m_pending.has_value(); }

    void run(Player* player)
    {
        for (;;)
        {
            std::unique_lock lock(m_mutex);
            m_cv.wait(lock, [this] { return m_pending.has_value() || m_quit; });
            if (!m_pending.has_value())
            {
                return;
            }
            lock.unlock();
            {
                rive::gpu::ScopedAutoreleasePool autoreleasePool;
                player->presentFrame(*m_pending);
            }
            lock.lock();
            m_pending.reset();
            lock.unlock();
            m_cv.notify_all();
        }
    }

    std::mutex m_mutex;
    std::condition_variable m_cv;
    std::optional<FrameJob> m_pending;
    bool m_quit = false;
    std::thread m_thread; // last, so the state above exists before it runs
};

Player::Player() : m_fps(std::make_unique<FPSOverlay>()) {}

// Joins before the replay state below goes, for hosts that skip shutdown.
Player::~Player() { m_renderThread = nullptr; }

void Player::shutdown()
{
    m_renderThread = nullptr;
#ifdef RIVE_CANVAS
    if (m_session != nullptr)
    {
        // Session made resources unwind through the session and the resident
        // tables against the live context, not at exit.
        m_fps.reset();
        m_scene = nullptr;
        m_artboard = nullptr;
        m_viewModelInstance = nullptr;
        m_file = nullptr;
        m_session = nullptr;
        m_replayer = nullptr;
    }
#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;
}

void Player::keyPressed(char key)
{
    if (key >= '0' && key <= '9')
    {
        m_keyMultiplier = m_keyMultiplier * 10 + (key - '0');
        m_seenDigit = true;
        return;
    }
    if (key == '!')
    {
        m_seenBang = true;
        return;
    }
    if (!m_seenDigit)
    {
        m_keyMultiplier = m_seenBang ? 0 : 1;
    }
    switch (key)
    {
        case 'h':
        case 'H':
            update_parameter(m_copiesLeft, m_keyMultiplier, key, m_seenBang);
            break;
        case 'k':
        case 'K':
            update_parameter(m_copiesAbove, m_keyMultiplier, key, m_seenBang);
            break;
        case 'l':
        case 'L':
            update_parameter(m_copiesRight, m_keyMultiplier, key, m_seenBang);
            break;
        case 'j':
        case 'J':
            update_parameter(m_copiesBelow, m_keyMultiplier, key, m_seenBang);
            break;
        case 'x':
        case 'X':
            update_parameter(m_copiesLeft, m_keyMultiplier, key, m_seenBang);
            update_parameter(m_copiesRight, m_keyMultiplier, key, m_seenBang);
            break;
        case 'y':
        case 'Y':
            update_parameter(m_copiesAbove, m_keyMultiplier, key, m_seenBang);
            update_parameter(m_copiesBelow, m_keyMultiplier, key, m_seenBang);
            break;
        case 'r':
        case 'R':
            update_parameter(m_rotations90, m_keyMultiplier, key, m_seenBang);
            break;
        case 'z':
        case 'Z':
            update_parameter(m_zoomLevel, m_keyMultiplier, key, m_seenBang);
            break;
        case 's':
        case 'S':
            update_parameter(m_spacing, m_keyMultiplier, key, m_seenBang);
            break;
        case 'm':
            m_monitorIdx += m_keyMultiplier;
            break;
        case 'p':
            m_paintStyle = (m_paintStyle + m_keyMultiplier) % 3;
            break;
        case 'P':
            m_paintStyle = (m_paintStyle + 3 - (m_keyMultiplier % 3)) % 3;
            break;
        case 'w':
            m_wireframe = !m_wireframe;
            break;
        case 'u':
            m_paused = !m_paused;
            break;
        case 'f':
            m_forceFixedDeltaTime = !m_forceFixedDeltaTime;
            break;
        case 'q':
        case '\x03': // ^C
            m_quit = true;
            break;
        case '\x1b': // Esc
            break;
        case '`':
            m_hotloadShaders = true;
            break;
        case '~':
            if (m_inputMode == InputMode::chars)
            {
                m_inputMode = InputMode::consolecommands;
            }
            else
            {
                m_inputMode = InputMode::chars;
            }
            break;
        default:
            // fprintf(stderr, "invalid option: %c\n", key);
            // abort();
            break;
    }
    m_keyMultiplier = 0;
    m_seenDigit = false;
    m_seenBang = false;
}

bool Player::parseArgs(int argc,
                       const char* const argv[],
                       FrameRunner::LaunchOptions& options)
{
    bool onlyUbershaders = false;
    // Applied after parsing, since --backend resets the backend params.
    std::optional<TestingWindow::BackendParams::PresentMode> presentMode;

    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(m_rivName,
                                                      m_pendingRivBytes))
            {
                fprintf(stderr, "failed to fetch a riv file.");
                abort();
            }
        }
        else if (strcmp(argv[i], "--backend") == 0 ||
                 strcmp(argv[i], "-b") == 0)
        {
            options.backend =
                TestingWindow::ParseBackend(argv[++i], &options.backendParams);
        }
        else if (argv[i][0] == '-' &&
                 argv[i][1] == 'b') // "-bvk" without a space.
        {
            options.backend =
                TestingWindow::ParseBackend(argv[i] + 2,
                                            &options.backendParams);
        }
        else if (strcmp(argv[i], "--options") == 0 ||
                 strcmp(argv[i], "-k") == 0)
        {
            for (const char* k = argv[++i]; *k; ++k)
            {
                keyPressed(*k);
            }
        }
        else if (strcmp(argv[i], "--only_ubershaders") == 0 ||
                 strcmp(argv[i], "-u") == 0)
        {
            onlyUbershaders = true;
        }
        else if (strcmp(argv[i], "--deferred") == 0)
        {
            m_useDeferred = true;
        }
        else if (strcmp(argv[i], "--fit") == 0 && i + 1 < argc)
        {
            const char* fit = argv[++i];
            m_fitSet = true;
            m_fit = strcmp(fit, "layout") == 0  ? rive::Fit::layout
                    : strcmp(fit, "cover") == 0 ? rive::Fit::cover
                    : strcmp(fit, "fill") == 0  ? rive::Fit::fill
                                                : rive::Fit::contain;
        }
        else if (strcmp(argv[i], "--present") == 0 && i + 1 < argc)
        {
            using PM = TestingWindow::BackendParams::PresentMode;
            const char* mode = argv[++i];
            if (strcmp(mode, "fifo") == 0)
            {
                presentMode = PM::fifo;
            }
            else if (strcmp(mode, "relaxed") == 0)
            {
                presentMode = PM::fifoRelaxed;
            }
            else if (strcmp(mode, "mailbox") == 0)
            {
                presentMode = PM::mailbox;
            }
            else if (strcmp(mode, "immediate") == 0)
            {
                presentMode = PM::immediate;
            }
            else
            {
                fprintf(stderr,
                        "--present must be fifo, relaxed, mailbox or "
                        "immediate, not %s\n",
                        mode);
                abort();
            }
        }
        else if (strcmp(argv[i], "--threaded") == 0)
        {
            m_threaded = true;
        }
        else if (strcmp(argv[i], "--dump") == 0 && i + 1 < argc)
        {
            m_dumpPath = argv[++i];
        }
        else if (strcmp(argv[i], "--dump-frame") == 0 && i + 1 < argc)
        {
            m_dumpFrame = atoi(argv[++i]);
        }
        else if (argv[i][0] == '-' &&
                 argv[i][1] == 'k') // "-k1234asdf" without a space.
        {
            for (const char* k = argv[i] + 2; *k; ++k)
            {
                keyPressed(*k);
            }
        }
        else if (strcmp(argv[i], "--window") == 0 || strcmp(argv[i], "-w") == 0)
        {
            options.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;
            }
            m_rivName = argv[i];
            std::ifstream rivStream(m_rivName, std::ios::binary);
            m_pendingRivBytes =
                std::vector<uint8_t>(std::istreambuf_iterator<char>(rivStream),
                                     {});
        }
    }

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

    return !m_pendingRivBytes.empty();
}

void Player::init()
{
    init(std::move(m_rivName), std::move(m_pendingRivBytes));
}

void Player::init(std::string rivName, std::vector<uint8_t> rivBytes)
{
    m_rivName = std::move(rivName);
    m_factory = TestingWindow::Get()->factory();
#ifdef RIVE_CANVAS
    // Importing through the DeferredSession makes the artboard's own 2D
    // resources deferred objects with ids so drawInternal can record.
    if (m_useDeferred)
    {
        if (auto* rc = TestingWindow::Get()->renderContext())
        {
            if (auto* ore = rc->getOreContext())
            {
                m_session = std::make_unique<rive::cmd::DeferredSession>(
                    rive::ore::ReplayCaps::from(*ore));
                // Bound before import so registration scripts that reach for
                // the device find it, like a real host.
                m_session->bindRenderContext(rc);
                declareTarget();
                m_replayer = std::make_unique<rive::cmd::DeferredReplayer>();
                m_factory = m_session.get();
            }
        }
        if (m_session == nullptr)
        {
            printf("--deferred unavailable on this backend, drawing "
                   "immediate\n");
        }
        else if (m_threaded && TestingWindow::Get()->supportsRenderThread())
        {
            m_renderThread = std::make_unique<RenderThread>(this);
        }
    }
#else
    if (m_useDeferred)
    {
        printf("--deferred requires a RIVE_CANVAS build, drawing immediate\n");
    }
#endif
    if (m_threaded && m_renderThread == nullptr)
    {
        printf("--threaded needs deferred replay on a window that presents "
               "off the main thread, presenting inline\n");
    }
    m_file = rive::File::import(rivBytes, m_factory);
    assert(m_file);

    m_artboard = m_file->artboardDefault();
    assert(m_artboard);
    // A layout artboard is authored to resize, so it fills the window like
    // our other hosts rather than letterboxing at its design size.
    if (!m_fitSet && m_artboard->style() != nullptr)
    {
        m_fit = rive::Fit::layout;
    }

    // Bind the artboard's default view model instance, if it has one, the same
    // way a real host runtime would.
    m_viewModelInstance =
        m_file->createDefaultViewModelInstance(m_artboard.get());
    if (m_viewModelInstance != nullptr)
    {
        m_artboard->bindViewModelInstance(m_viewModelInstance);
    }

    auto stateMachine = m_artboard->defaultStateMachine();
    if (!stateMachine && m_artboard->stateMachineCount() > 0)
    {
        stateMachine = m_artboard->stateMachineAt(0);
    }
    m_stateMachine = stateMachine.get();
    m_scene = std::move(stateMachine);
    if (!m_scene)
    {
        m_scene = m_artboard->animationAt(0);
    }
    assert(m_scene);
    if (m_viewModelInstance != nullptr)
    {
        m_scene->bindViewModelInstance(m_viewModelInstance);
    }

    // Setup FPS.
    m_fps->roboto = HBFont::Decode(assets::roboto_flex_ttf());
    m_fps->blackStroke = m_factory->makeRenderPaint();
    m_fps->blackStroke->color(0xff000000);
    m_fps->blackStroke->style(rive::RenderPaintStyle::stroke);
    m_fps->blackStroke->thickness(4);
    m_fps->whiteFill = m_factory->makeRenderPaint();
    m_fps->whiteFill->color(0xffffffff);
    m_fps->timeLastUpdate = std::chrono::high_resolution_clock::now();
    m_timestampPrevFrame = std::chrono::high_resolution_clock::now();
}

// The state machine takes gamepads as the wire batch our js embedder sends.
static void appendU32(std::vector<uint8_t>& buffer, uint32_t value)
{
    for (int i = 0; i < 4; ++i)
    {
        buffer.push_back(static_cast<uint8_t>(value >> (8 * i)));
    }
}

void Player::submitGamepad(const TestingWindow::InputEventData& event)
{
    if (m_stateMachine == nullptr)
    {
        return;
    }
    const auto& pad = event.metadata.pad;
    std::vector<uint8_t> buffer;
    appendU32(buffer, rive::kGamepadBatchWireVersion);
    if (event.eventType == TestingWindow::InputEvent::GamepadConnected)
    {
        buffer.push_back(
            static_cast<uint8_t>(rive::GamepadRecordType::connected));
        appendU32(buffer, pad.deviceId);
        buffer.push_back(0); // standard mapping
        buffer.push_back(pad.buttonCount);
        buffer.push_back(pad.axisCount);
        buffer.push_back(0); // padding
        for (int i = 0; i < pad.buttonCount + pad.axisCount; ++i)
        {
            appendU32(buffer, 0); // every value at rest
        }
    }
    else if (event.eventType == TestingWindow::InputEvent::GamepadDisconnected)
    {
        buffer.push_back(
            static_cast<uint8_t>(rive::GamepadRecordType::disconnected));
        appendU32(buffer, pad.deviceId);
    }
    else
    {
        buffer.push_back(static_cast<uint8_t>(rive::GamepadRecordType::update));
        appendU32(buffer, pad.deviceId);
        buffer.push_back(1); // one change
        buffer.push_back(pad.isAxis ? 1 : 0);
        buffer.push_back(pad.index);
        uint32_t bits;
        memcpy(&bits, &pad.value, sizeof(bits));
        appendU32(buffer, bits);
    }
    m_stateMachine->submitGamepadsFromBuffer(buffer.data(), buffer.size());
}

#ifdef RIVE_CANVAS
void Player::declareTarget()
{
    TestingWindow* window = TestingWindow::Get();
    TestingWindow::OreTarget target = window->oreTarget();
    m_session->oreContext().setTarget(
        target.exposed
            ? rive::ore::Context::TargetDesc::color8(window->width(),
                                                     window->height(),
                                                     target.bgra)
            : rive::ore::Context::TargetDesc{});
}
#endif

void Player::presentFrame(FrameJob& job)
{
#ifdef RIVE_CANVAS
    if (m_session != nullptr)
    {
        TestingWindowFrameSink sink(job.options);
        m_replayer->replayFrame(job.frame, sink);
        uint32_t dropped = m_replayer->droppedDraws();
        if (dropped != 0 && dropped != m_lastDroppedDraws)
        {
            printf("deferred replay dropped %u draws\n", dropped);
        }
        m_lastDroppedDraws = dropped;
    }
#endif
    TestingWindow::Get()->endFrame(job.pixels);
}

bool Player::doFrame()
{
    if (m_quit || TestingWindow::Get()->shouldQuit()
#if defined(RIVE_ANDROID) && !defined(RIVE_UNREAL)
        || !rive_android_app_poll_once()
#endif
    )
    {
        m_quit = true;
        return false;
    }

#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);
            if (m_renderThread != nullptr)
            {
                m_renderThread->drain();
            }
            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 (m_forceFixedDeltaTime)
    {
        advanceDeltaTime = 1.0f / 120;
    }

    // advanceAndApply drives the artboard through advanceInternal, which
    // skips the async-work pump in Artboard::advance; pump it here so scripted
    // image decodes resolve (without threads they only run when polled).
    m_artboard->pollAsyncWork();
#ifdef WITH_RIVE_SCRIPTING_WASM
    // Scavenges the script nursery, which otherwise grows until it traps.
    if (const char* warning = m_file->frameBoundary())
    {
        fprintf(stderr, "%s\n", warning);
    }
#endif
    m_scene->advanceAndApply(m_paused ? 0 : advanceDeltaTime);

    m_copiesLeft = std::max(m_copiesLeft, 0);
    m_copiesAbove = std::max(m_copiesAbove, 0);
    m_copiesRight = std::max(m_copiesRight, 0);
    m_copiesBelow = std::max(m_copiesBelow, 0);
    int copyCount = (m_copiesLeft + 1 + m_copiesRight) *
                    (m_copiesAbove + 1 + m_copiesBelow);
    if (copyCount != m_lastReportedCopyCount ||
        m_paused != m_lastReportedPauseState)
    {
        printf("Drawing %i copies of %s%s at %u x %u\n",
               copyCount,
               m_rivName.c_str(),
               m_paused ? " (paused)" : "",
               TestingWindow::Get()->width(),
               TestingWindow::Get()->height());
        m_lastReportedCopyCount = copyCount;
        m_lastReportedPauseState = m_paused;
    }

    const TestingWindow::FrameOptions frameOptions = {
        .clearColor = 0xff303030,
        .doClear = true,
        .wireframe = m_wireframe,
        .fillsDisabled = m_paintStyle == 2,
        .strokesDisabled = m_paintStyle == 1,
    };
    std::unique_ptr<rive::Renderer> renderer;
#ifdef RIVE_CANVAS
    if (m_session != nullptr)
    {
        declareTarget();
        m_session->recordOreReplayMarker();
        renderer = m_session->makeScreenRenderer();
    }
    else
#endif
    {
        renderer = TestingWindow::Get()->beginFrame(frameOptions);
    }

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

    renderer->save();

    uint32_t width = TestingWindow::Get()->width();
    uint32_t height = TestingWindow::Get()->height();
    for (int i = m_rotations90; (i & 3) != 0; --i)
    {
        renderer->transform(rive::Mat2D(0, 1, -1, 0, width, 0));
        std::swap(height, width);
    }
    if (m_fit == rive::Fit::layout &&
        (m_artboard->width() != width || m_artboard->height() != height))
    {
        m_artboard->width(width);
        m_artboard->height(height);
        m_artboard->advance(0.0f);
    }
    if (m_zoomLevel != 0)
    {
        float scale = powf(1.25f, m_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(m_fit,
                    rive::Alignment::center,
                    rive::AABB(0, 0, width, height),
                    m_artboard->bounds());
    float spacingPx = m_spacing * 5 + 150;
    renderer->translate(-spacingPx * m_copiesLeft, -spacingPx * m_copiesAbove);
    for (int y = -m_copiesAbove; y <= m_copiesBelow; ++y)
    {
        renderer->save();
        for (int x = -m_copiesLeft; x <= m_copiesRight; ++x)
        {
            m_artboard->drawInternal(renderer.get());
            renderer->translate(spacingPx, 0);
        }
        renderer->restore();
        renderer->translate(0, spacingPx);
    }
    renderer->restore();

    if (m_fps->text != nullptr)
    {
        // Draw FPS.
        renderer->save();
        renderer->translate(0, 20);
        m_fps->text->render(renderer.get(), m_fps->blackStroke);
        m_fps->text->render(renderer.get(), m_fps->whiteFill);
        renderer->restore();
    }

    renderer->restore();

    std::vector<uint8_t> pixels;
    const bool dump = !m_dumpPath.empty() && ++m_frameCounter >= m_dumpFrame;
    FrameJob job = {.options = frameOptions,
                    .pixels = dump ? &pixels : nullptr};
#ifdef RIVE_CANVAS
    if (m_session != nullptr)
    {
        // Snapshot replay is the same path a threaded consumer takes.
        job.frame = rive::cmd::snapshotFrame(*m_session);
        m_session->resetFrame();
    }
#endif
    if (m_renderThread != nullptr)
    {
        m_renderThread->submit(std::move(job));
        if (dump)
        {
            m_renderThread->drain();
        }
    }
    else
    {
        presentFrame(job);
    }
    if (dump)
    {
        uint32_t w = TestingWindow::Get()->width();
        uint32_t h = TestingWindow::Get()->height();
        if (FILE* f = fopen(m_dumpPath.c_str(), "wb"))
        {
            fwrite(&w, sizeof(w), 1, f);
            fwrite(&h, sizeof(h), 1, f);
            fwrite(pixels.data(), 1, pixels.size(), f);
            fclose(f);
            printf("dumped %ux%u frame (%zu bytes) to %s\n",
                   w,
                   h,
                   pixels.size(),
                   m_dumpPath.c_str());
        }
        else
        {
            fprintf(stderr,
                    "could not open dump path %s\n",
                    m_dumpPath.c_str());
        }
        m_quit = true;
        return false;
    }

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

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

        m_fps->frames = 0;
        m_fps->timeLastUpdate = timeNow;
    }

    const rive::Mat2D alignmentMat =
        computeAlignment(m_fit,
                         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))
    {
        // Only pointer events carry a position in the union.
        auto alignedPos = [&]() {
            return alignmentMat.invertOrIdentity() *
                   rive::Vec2D(inputEventData.metadata.posX,
                               inputEventData.metadata.posY);
        };
        switch (inputEventData.eventType)
        {
            case TestingWindow::InputEvent::KeyPress:
                keyPressed(inputEventData.metadata.key);
                break;

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

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

            case TestingWindow::InputEvent::MouseUp:
                m_scene->pointerUp(alignedPos());
                break;
            case TestingWindow::InputEvent::GamepadConnected:
            case TestingWindow::InputEvent::GamepadDisconnected:
            case TestingWindow::InputEvent::GamepadChange:
                submitGamepad(inputEventData);
                break;
        }
    }

    std::string command;
    char key;

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

        std::istringstream iss(command);
        std::string first, second;
        iss >> first >> second;
        if (first == "~")
        {
            m_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))
        {
            keyPressed(key);
        }
    }

    return true;
}

// Unreal owns the main loop: it creates its own Player, parses the same
// arguments through Player::parseArgs(), and pumps doFrame() once per engine
// tick. Everything below (the global player, the shutdown, and main() itself)
// is only for the standalone tool.
#ifndef RIVE_UNREAL

static Player player;

static void player_shutdown()
{
    printf("\nShutting down\n");
    player.shutdown();
    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
}

#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

    FrameRunner::LaunchOptions options;
    const bool haveRiv = player.parseArgs(argc, argv, options);

    TestingWindow::Init(options.backend,
                        options.backendParams,
                        options.visibility,
#ifdef RIVE_ANDROID
                        rive_android_app_wait_for_window()
#elif defined(RIVE_IOS) || defined(RIVE_IOS_SIMULATOR)
                        rive_ios_app_wait_for_window()
#else
                        reinterpret_cast<void*>(
                            static_cast<intptr_t>(player.monitorIdx()))
#endif
    );

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

    player.init();

#ifdef __EMSCRIPTEN__
    emscripten_set_main_loop(
        []() {
            if (!player.doFrame())
            {
                player_shutdown();
            }
        },
        0,
        true);
#else
    for (;;)
    {
        rive::gpu::ScopedAutoreleasePool autoreleasePool;
        if (!player.doFrame())
        {
            player_shutdown();
        }
    }
#endif

    return 0;
}

#endif // !RIVE_UNREAL

#endif
