/*
 * Copyright 2026 Rive
 *
 * A canvas sampling another canvas replays after its writer regardless of
 * record order, so the reversed recording must match the in-order one. The
 * cycle GM pins the demoted back edge to previous-frame sampling.
 */

#include "gm.hpp"
#include "gmutils.hpp"

#if defined(WITH_RIVE_SCRIPTING) && defined(RIVE_CANVAS)

#include "rive/renderer/render_canvas.hpp"
#include "rive/renderer/rive_renderer.hpp"
#include "rive/renderer/cmd/deferred_replayer.hpp"
#include "rive/renderer/cmd/deferred_session.hpp"

using namespace rivegm;
using namespace rive;
using namespace rive::gpu;

namespace
{
// DeferredFrameSink over the GM harness. The harness frame is already open,
// so the first sink action flushes it and later frames resume with preserve.
class DagGMSink : public rive::cmd::DeferredFrameSink
{
public:
    DagGMSink(RenderContext* rc,
              const RenderContext::FrameDescriptor& mainDesc) :
        m_rc(rc), m_mainDesc(mainDesc)
    {}

    Factory* factory() override { return TestingWindow::Get()->factory(); }

    // The GM harness owns one main render target.
    Renderer* beginScreenFrame(uint64_t target) override
    {
        assert(target == 0);
        flushOpenFrame();
        auto d = m_mainDesc;
        d.loadAction = LoadAction::preserveRenderTarget;
        m_rc->beginFrame(std::move(d));
        m_frameOpen = true;
        m_screen = std::make_unique<RiveRenderer>(m_rc);
        return m_screen.get();
    }

    Renderer* beginCanvasContent(RenderCanvas* canvas,
                                 uint32_t clearColor) override
    {
        flushOpenFrame();
        m_activeCanvas = canvas;
        auto d = m_mainDesc;
        d.renderTargetWidth = canvas->width();
        d.renderTargetHeight = canvas->height();
        d.loadAction = LoadAction::clear;
        d.clearColor = clearColor;
        m_rc->beginFrame(std::move(d));
        m_frameOpen = true;
        m_canvasRenderer = std::make_unique<RiveRenderer>(m_rc);
        return m_canvasRenderer.get();
    }

    void endCanvasContent() override
    {
        if (m_activeCanvas == nullptr)
        {
            return;
        }
        TestingWindow::Get()->flushPLSContext(m_activeCanvas->renderTarget());
        m_frameOpen = false;
        m_canvasRenderer = nullptr;
        m_activeCanvas = nullptr;
    }

private:
    // The harness (or the previous replay) leaves the main frame open.
    void flushOpenFrame()
    {
        if (!m_flushedHarnessFrame || m_frameOpen)
        {
            TestingWindow::Get()->flushPLSContext();
            m_flushedHarnessFrame = true;
            m_frameOpen = false;
        }
    }

    RenderContext* m_rc;
    RenderContext::FrameDescriptor m_mainDesc;
    bool m_flushedHarnessFrame = false;
    bool m_frameOpen = false;
    std::unique_ptr<RiveRenderer> m_screen;
    std::unique_ptr<RiveRenderer> m_canvasRenderer;
    RenderCanvas* m_activeCanvas = nullptr;
};

rcp<RenderPath> ovalPath(rive::cmd::DeferredSession& session, AABB bounds)
{
    RawPath raw;
    raw.addOval(bounds);
    return session.makeRenderPath(raw, FillRule::nonZero);
}

rcp<RenderPaint> solidPaint(rive::cmd::DeferredSession& session, ColorInt color)
{
    auto paint = session.makeRenderPaint();
    paint->color(color);
    return paint;
}

void drawCanvasImage(Renderer* r,
                     RenderCanvas* canvas,
                     float x,
                     float y,
                     bool flip)
{
    r->save();
    r->translate(x, y);
    if (flip)
    {
        r->translate(0, static_cast<float>(canvas->height()));
        r->scale(1, -1);
    }
    r->drawImage(canvas->renderImage(),
                 {.filter = ImageFilter::nearest},
                 BlendMode::srcOver,
                 1.0f);
    r->restore();
}

void replayFrameThroughGM(rive::cmd::DeferredSession& session,
                          rive::cmd::DeferredReplayer& replayer,
                          RenderContext* rc,
                          const RenderContext::FrameDescriptor& mainDesc)
{
    rive::cmd::DeferredFrame frame = rive::cmd::snapshotFrame(session);
    session.resetFrame();
    DagGMSink sink(rc, mainDesc);
    replayer.replayFrame(frame, sink);
}
} // namespace

// Canvas B samples canvas A; reversed records B's bracket first. Both GMs
// must produce identical pixels: the schedule, not record order, decides.
class CanvasDagChainGM : public GM
{
public:
    CanvasDagChainGM(bool reversed) : GM(256, 256), m_reversed(reversed) {}

    ColorInt clearColor() const override { return 0xff202028; }

    void onDraw(Renderer*) override
    {
        auto rc = TestingWindow::Get()->renderContext();
        if (!rc)
        {
            return;
        }
        auto canvasA = rc->makeRenderCanvas(128, 128);
        auto canvasB = rc->makeRenderCanvas(128, 128);
        if (!canvasA || !canvasB)
        {
            return;
        }
        auto mainDesc = rc->frameDescriptor();
        bool flip = rc->platformFeatures().framebufferBottomUp;

        rive::cmd::DeferredSession session(nullptr);
        rive::cmd::DeferredReplayer replayer;
        auto green = solidPaint(session, 0xff30c060);
        auto orange = solidPaint(session, 0xffe08830);
        auto circle = ovalPath(session, {24, 24, 104, 104});
        auto dot = ovalPath(session, {8, 8, 40, 40});

        auto recordA = [&]() {
            Renderer* a = session.beginCanvasContent(canvasA.get(), 0xff103050);
            a->drawPath(circle.get(), green.get());
            session.endCanvasContent(canvasA.get());
        };
        auto recordB = [&]() {
            // B composites A, then draws its own dot on top.
            Renderer* b = session.beginCanvasContent(canvasB.get(), 0xff501030);
            drawCanvasImage(b, canvasA.get(), 0, 0, flip);
            b->drawPath(dot.get(), orange.get());
            session.endCanvasContent(canvasB.get());
        };
        if (m_reversed)
        {
            recordB();
            recordA();
        }
        else
        {
            recordA();
            recordB();
        }
        auto screen = session.makeScreenRenderer();
        drawCanvasImage(screen.get(), canvasA.get(), 0, 64, flip);
        drawCanvasImage(screen.get(), canvasB.get(), 128, 64, flip);

        replayFrameThroughGM(session, replayer, rc, mainDesc);
    }

private:
    bool m_reversed;
};

GMREGISTER(canvas_dag_chain, return new CanvasDagChainGM(false))
GMREGISTER(canvas_dag_chain_reversed, return new CanvasDagChainGM(true))

// A samples B while B samples A. The demoted back edge samples the previous
// frame by contract: frame two must show frame one's content crossed over,
// deterministic because frame one seeded both canvases.
class CanvasDagCycleGM : public GM
{
public:
    CanvasDagCycleGM() : GM(256, 256) {}

    ColorInt clearColor() const override { return 0xff202028; }

    void onDraw(Renderer*) override
    {
        auto rc = TestingWindow::Get()->renderContext();
        if (!rc)
        {
            return;
        }
        auto canvasA = rc->makeRenderCanvas(128, 128);
        auto canvasB = rc->makeRenderCanvas(128, 128);
        if (!canvasA || !canvasB)
        {
            return;
        }
        auto mainDesc = rc->frameDescriptor();
        bool flip = rc->platformFeatures().framebufferBottomUp;

        rive::cmd::DeferredSession session(nullptr);
        rive::cmd::DeferredReplayer replayer;

        // Frame one: seed A green, B orange, no cross sampling.
        {
            auto green = solidPaint(session, 0xff30c060);
            auto orange = solidPaint(session, 0xffe08830);
            auto circle = ovalPath(session, {24, 24, 104, 104});
            Renderer* a = session.beginCanvasContent(canvasA.get(), 0xff103050);
            a->drawPath(circle.get(), green.get());
            session.endCanvasContent(canvasA.get());
            Renderer* b = session.beginCanvasContent(canvasB.get(), 0xff501030);
            b->drawPath(circle.get(), orange.get());
            session.endCanvasContent(canvasB.get());
            replayFrameThroughGM(session, replayer, rc, mainDesc);
        }

        // Frame two: each canvas samples the other shrunken, then the screen
        // shows both. The back edge sees frame one's pixels.
        {
            auto white = solidPaint(session, 0xffffffff);
            auto dot = ovalPath(session, {4, 4, 24, 24});
            Renderer* a = session.beginCanvasContent(canvasA.get(), 0xff103050);
            a->save();
            a->scale(0.5f, 0.5f);
            drawCanvasImage(a, canvasB.get(), 0, 0, flip);
            a->restore();
            a->drawPath(dot.get(), white.get());
            session.endCanvasContent(canvasA.get());

            Renderer* b = session.beginCanvasContent(canvasB.get(), 0xff501030);
            b->save();
            b->scale(0.5f, 0.5f);
            drawCanvasImage(b, canvasA.get(), 0, 0, flip);
            b->restore();
            b->drawPath(dot.get(), white.get());
            session.endCanvasContent(canvasB.get());

            auto screen = session.makeScreenRenderer();
            drawCanvasImage(screen.get(), canvasA.get(), 0, 64, flip);
            drawCanvasImage(screen.get(), canvasB.get(), 128, 64, flip);
            replayFrameThroughGM(session, replayer, rc, mainDesc);
        }
    }
};

GMREGISTER(canvas_dag_cycle, return new CanvasDagCycleGM())

#else

// Canvas or scripting disabled: nothing to register.

#endif
