/*
 * Copyright 2024 Rive
 */

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

#include "player.hpp"

#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/renderer.hpp"
#include "rive/scene.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
#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 <fstream>

#if defined(RIVE_ANDROID) && !defined(RIVE_UNREAL)
#include "common/rive_android_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;
};

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

Player::~Player() = default;

void Player::shutdown()
{
#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_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;

    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 (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 (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);
                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_useDeferred)
    {
        printf("--deferred requires a RIVE_CANVAS build, drawing immediate\n");
    }
#endif
    m_file = rive::File::import(rivBytes, m_factory);
    assert(m_file);

    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_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();
}

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);
            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;
    }

    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)
    {
        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");
        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_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(rive::Fit::contain,
                    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();
#ifdef RIVE_CANVAS
    if (m_session != nullptr)
    {
        // Snapshot replay is the same path a threaded consumer takes.
        rive::cmd::DeferredFrame frame = rive::cmd::snapshotFrame(*m_session);
        m_session->resetFrame();
        TestingWindowFrameSink sink(frameOptions);
        m_replayer->replayFrame(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();

    // 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(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:
                keyPressed(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 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()
#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 (;;)
    {
        if (!player.doFrame())
        {
            player_shutdown();
        }
    }
#endif

    return 0;
}

#endif // !RIVE_UNREAL

#endif
