/*
 * Copyright 2026 Rive
 */

#include "utils/serialized_replay.hpp"
#include "utils/serialize_ops.hpp"
#include "rive/core/binary_reader.hpp"
#include "rive/math/mat2d.hpp"
#include "utils/no_op_renderer.hpp"
#include <unordered_map>
#include <vector>

using namespace rive;

namespace
{
// Absent ids mean a truncated or corrupt stream; callers fail instead of
// dereferencing a null resource.
template <typename T>
T* find(std::unordered_map<uint64_t, rcp<T>>& map, uint64_t id)
{
    auto it = map.find(id);
    return it != map.end() ? it->second.get() : nullptr;
}
} // namespace

bool rive::replaySerializedCommands(Span<const uint8_t> stream,
                                    Factory* factory,
                                    Renderer* renderer,
                                    const SerializedReplayHooks& hooks)
{
    BinaryReader reader(stream);
    if (reader.readByte() != 'S' || reader.readByte() != 'R' ||
        reader.readByte() != 'I' || reader.readByte() != 'V')
    {
        return false;
    }
    if (reader.readVarUint64() != 1)
    {
        return false;
    }

    std::unordered_map<uint64_t, rcp<RenderPath>> paths;
    std::unordered_map<uint64_t, rcp<RenderPaint>> paints;
    std::unordered_map<uint64_t, rcp<RenderShader>> shaders;
    std::unordered_map<uint64_t, rcp<RenderImage>> images;
    std::unordered_map<uint64_t, rcp<RenderBuffer>> buffers;
    std::unordered_map<uint64_t, rcp<ImageMeshInstances>> meshInstances;

    // Cache-as-bitmap. A canvas is declared by makeRenderCanvas, its content
    // arrives inline between canvasContentBegin/End, and the composite that
    // samples it is an ordinary drawImage of the same id -- so a canvas image
    // lands in `images` alongside the decoded ones.
    struct CanvasSize
    {
        uint32_t width;
        uint32_t height;
    };
    std::unordered_map<uint64_t, CanvasSize> canvasSizes;
    // Where the ops currently being read draw. The screen renderer at the
    // bottom, a host-supplied one for each open canvas, and the null sink for
    // a canvas the host declined -- its content still has to parse (later ops
    // reference resources declared inside it) but must not reach the screen.
    NoOpRenderer droppedContent;
    Renderer* active = renderer;
    // One entry per open canvas bracket. The id rides along with the renderer
    // it interrupted so an end can be checked against the begin that opened
    // it; without it the stack depth is the only thing validated, and a
    // mismatched end would close the wrong canvas and still report success.
    struct OpenCanvas
    {
        uint64_t id;
        Renderer* interruptedRenderer;
    };
    std::vector<OpenCanvas> interrupted;

    while (!reader.reachedEnd())
    {
        SerializeOp op = static_cast<SerializeOp>(reader.readVarUint64());
        if (reader.hasError())
            return false;
        switch (op)
        {
            case SerializeOp::makeRenderPath:
            {
                uint64_t id = reader.readVarUint64();
                // Geometry and fill rule arrive as later ops.
                paths[id] = factory->makeEmptyRenderPath();
                break;
            }
            case SerializeOp::makeRenderPaint:
            {
                uint64_t id = reader.readVarUint64();
                paints[id] = factory->makeRenderPaint();
                break;
            }
            case SerializeOp::rewind:
            {
                uint64_t id = reader.readVarUint64();
                RenderPath* path = find(paths, id);
                if (path == nullptr)
                    return false;
                path->rewind();
                break;
            }
            case SerializeOp::fillRule:
            {
                uint64_t id = reader.readVarUint64();
                RenderPath* path = find(paths, id);
                if (path == nullptr)
                    return false;
                path->fillRule(static_cast<FillRule>(reader.readVarUint64()));
                break;
            }
            case SerializeOp::addRawPath:
            {
                uint64_t id = reader.readVarUint64();
                RenderPath* path = find(paths, id);
                if (path == nullptr)
                    return false;
                RawPath rp = deserializeRawPath(reader);
                path->addRawPath(rp);
                break;
            }
            case SerializeOp::color:
            {
                uint64_t id = reader.readVarUint64();
                RenderPaint* paint = find(paints, id);
                if (paint == nullptr)
                    return false;
                paint->color(static_cast<unsigned int>(reader.readVarUint64()));
                break;
            }
            case SerializeOp::style:
            {
                uint64_t id = reader.readVarUint64();
                RenderPaint* paint = find(paints, id);
                if (paint == nullptr)
                    return false;
                // The stream writes 0 for stroke and 1 for fill.
                bool stroked = reader.readVarUint64() == 0;
                paint->style(stroked ? RenderPaintStyle::stroke
                                     : RenderPaintStyle::fill);
                break;
            }
            case SerializeOp::thickness:
            {
                uint64_t id = reader.readVarUint64();
                RenderPaint* paint = find(paints, id);
                if (paint == nullptr)
                    return false;
                paint->thickness(reader.readFloat32());
                break;
            }
            case SerializeOp::join:
            {
                uint64_t id = reader.readVarUint64();
                RenderPaint* paint = find(paints, id);
                if (paint == nullptr)
                    return false;
                paint->join(static_cast<StrokeJoin>(reader.readVarUint64()));
                break;
            }
            case SerializeOp::cap:
            {
                uint64_t id = reader.readVarUint64();
                RenderPaint* paint = find(paints, id);
                if (paint == nullptr)
                    return false;
                paint->cap(static_cast<StrokeCap>(reader.readVarUint64()));
                break;
            }
            case SerializeOp::feather:
            {
                uint64_t id = reader.readVarUint64();
                RenderPaint* paint = find(paints, id);
                if (paint == nullptr)
                    return false;
                paint->feather(reader.readFloat32());
                break;
            }
            case SerializeOp::blendMode:
            {
                uint64_t id = reader.readVarUint64();
                RenderPaint* paint = find(paints, id);
                if (paint == nullptr)
                    return false;
                paint->blendMode(
                    static_cast<BlendMode>(reader.readVarUint64()));
                break;
            }
            case SerializeOp::additiveness:
            {
                uint64_t id = reader.readVarUint64();
                RenderPaint* paint = find(paints, id);
                if (paint == nullptr)
                    return false;
                paint->additiveness(reader.readFloat32());
                break;
            }
            case SerializeOp::strokePosition:
            {
                uint64_t id = reader.readVarUint64();
                uint64_t position = reader.readVarUint64();
                RenderPaint* paint = find(paints, id);
                // Renderers assert on a position they don't know.
                if (paint == nullptr ||
                    position > (uint64_t)StrokePosition::outside)
                    return false;
                paint->strokePosition(static_cast<StrokePosition>(position));
                break;
            }
            case SerializeOp::shader:
            {
                uint64_t id = reader.readVarUint64();
                uint64_t shaderId = reader.readVarUint64();
                RenderPaint* paint = find(paints, id);
                if (paint == nullptr)
                    return false;
                // The stream writes 0 for both nullptr and shader id 0. The map
                // resolves it since a missing entry yields a null rcp.
                paint->shader(shaders[shaderId]);
                break;
            }
            case SerializeOp::paintModulatedImage:
            {
                uint64_t id = reader.readVarUint64();
                uint64_t rawImageId = reader.readVarUint64();
                auto filter = static_cast<ImageFilter>(reader.readVarUint64());
                auto wrapX = static_cast<ImageWrap>(reader.readVarUint64());
                auto wrapY = static_cast<ImageWrap>(reader.readVarUint64());
                float xx = reader.readFloat32();
                float xy = reader.readFloat32();
                float yx = reader.readFloat32();
                float yy = reader.readFloat32();
                float tx = reader.readFloat32();
                float ty = reader.readFloat32();
                RenderPaint* paint = find(paints, id);
                if (paint == nullptr)
                    return false;
                // Image id is offset by one; 0 means no image.
                RenderImage* image =
                    rawImageId == 0 ? nullptr : images[rawImageId - 1].get();
                ImageSampler sampler;
                sampler.filter = filter;
                sampler.wrapX = wrapX;
                sampler.wrapY = wrapY;
                paint->modulatedImage(image,
                                      sampler,
                                      Mat2D(xx, xy, yx, yy, tx, ty));
                break;
            }
            case SerializeOp::makeLinearGradient:
            case SerializeOp::makeRadialGradient:
            {
                uint64_t id = reader.readVarUint64();
                size_t count = static_cast<size_t>(reader.readVarUint64());
                std::vector<ColorInt> colors(count);
                std::vector<float> stops(count);
                for (size_t i = 0; i < count; ++i)
                {
                    colors[i] = static_cast<ColorInt>(reader.readVarUint64());
                    stops[i] = reader.readFloat32();
                }
                float a = reader.readFloat32();
                float b = reader.readFloat32();
                float c = reader.readFloat32();
                if (op == SerializeOp::makeLinearGradient)
                {
                    float d = reader.readFloat32();
                    shaders[id] = factory->makeLinearGradient(a,
                                                              b,
                                                              c,
                                                              d,
                                                              colors.data(),
                                                              stops.data(),
                                                              count);
                }
                else
                {
                    shaders[id] = factory->makeRadialGradient(a,
                                                              b,
                                                              c,
                                                              colors.data(),
                                                              stops.data(),
                                                              count);
                }
                break;
            }
            case SerializeOp::decodeImage:
            {
                uint64_t id = reader.readVarUint64();
                size_t size = static_cast<size_t>(reader.readVarUint64());
                Span<const uint8_t> data = reader.readBytes(size);
                images[id] = factory->decodeImage(data);
                break;
            }
            case SerializeOp::makeRenderBuffer:
            {
                uint64_t id = reader.readVarUint64();
                size_t size = static_cast<size_t>(reader.readVarUint64());
                auto type =
                    static_cast<RenderBufferType>(reader.readVarUint64());
                auto flags =
                    static_cast<RenderBufferFlags>(reader.readVarUint64());
                buffers[id] = factory->makeRenderBuffer(type, flags, size);
                break;
            }
            case SerializeOp::setVertexBufferData:
            case SerializeOp::setIndexBufferData:
            {
                uint64_t id = reader.readVarUint64();
                RenderBuffer* buf = find(buffers, id);
                if (buf == nullptr)
                    return false;
                void* mapped = buf->map();
                if (op == SerializeOp::setVertexBufferData)
                {
                    size_t n = buf->sizeInBytes() / sizeof(float);
                    float* out = static_cast<float*>(mapped);
                    for (size_t i = 0; i < n; ++i)
                        out[i] = reader.readFloat32();
                }
                else
                {
                    size_t n = buf->sizeInBytes() / sizeof(uint16_t);
                    uint16_t* out = static_cast<uint16_t*>(mapped);
                    for (size_t i = 0; i < n; ++i)
                        out[i] = static_cast<uint16_t>(reader.readVarUint64());
                }
                buf->unmap();
                break;
            }
            case SerializeOp::save:
                active->save();
                break;
            case SerializeOp::restore:
                active->restore();
                break;
            case SerializeOp::transform:
            {
                float m[6];
                for (int i = 0; i < 6; ++i)
                    m[i] = reader.readFloat32();
                active->transform(Mat2D(m[0], m[1], m[2], m[3], m[4], m[5]));
                break;
            }
            case SerializeOp::modulateOpacity:
                active->modulateOpacity(reader.readFloat32());
                break;
            case SerializeOp::modulateColor:
            {
                ColorInt color = (ColorInt)reader.readVarUint64();
                active->modulateColor(color, reader.readVarUint64() != 0);
                break;
            }
            case SerializeOp::drawPath:
            {
                uint64_t pathId = reader.readVarUint64();
                uint64_t paintId = reader.readVarUint64();
                RenderPath* path = find(paths, pathId);
                RenderPaint* paint = find(paints, paintId);
                if (path == nullptr || paint == nullptr)
                    return false;
                active->drawPath(path, paint);
                break;
            }
            case SerializeOp::clipPath:
            {
                uint64_t pathId = reader.readVarUint64();
                RenderPath* path = find(paths, pathId);
                if (path == nullptr)
                    return false;
                active->clipPath(path);
                break;
            }
            case SerializeOp::applyLayerMask:
            {
                uint64_t maskId = reader.readVarUint64();
                auto mode = static_cast<LayerMaskMode>(reader.readVarUint64());
                // Null when a decode failed or when the host declined the
                // canvas this id names. Skipping leaves the layer unmasked,
                // which is the same degradation the feature falls back to
                // everywhere else, and the rest of the frame still replays.
                if (RenderImage* mask = find(images, maskId))
                {
                    active->applyLayerMask(mask,
                                           ImageSampler::LinearClamp(),
                                           mode);
                }
                break;
            }
            case SerializeOp::drawImage:
            case SerializeOp::drawImageAdditive:
            {
                uint64_t imageId = reader.readVarUint64();
                auto blend = static_cast<BlendMode>(reader.readVarUint64());
                float opacity = reader.readFloat32();
                // Only the additive variant carries the trailing float; the
                // plain op means an additiveness of 0.
                float additiveness = op == SerializeOp::drawImageAdditive
                                         ? reader.readFloat32()
                                         : 0.0f;
                // Null when a decode failed or when the host declined the
                // canvas this id names; either way there is nothing to
                // composite and the rest of the frame still replays.
                if (RenderImage* image = find(images, imageId))
                {
                    active->drawImage(image,
                                      ImageSampler::LinearClamp(),
                                      blend,
                                      opacity,
                                      additiveness);
                }
                break;
            }
            case SerializeOp::drawImageMesh:
            case SerializeOp::drawImageMeshAdditive:
            {
                RenderImage* image = find(images, reader.readVarUint64());
                auto blend = static_cast<BlendMode>(reader.readVarUint64());
                float opacity = reader.readFloat32();
                RenderBuffer* pos = find(buffers, reader.readVarUint64());
                RenderBuffer* uvs = find(buffers, reader.readVarUint64());
                RenderBuffer* idx = find(buffers, reader.readVarUint64());
                float additiveness = op == SerializeOp::drawImageMeshAdditive
                                         ? reader.readFloat32()
                                         : 0.0f;
                // Draws referring to failed or invalid objects are dropped.
                if (image != nullptr && pos != nullptr && uvs != nullptr &&
                    idx != nullptr)
                {
                    uint32_t vertexCount = static_cast<uint32_t>(
                        pos->sizeInBytes() / (2 * sizeof(float)));
                    uint32_t indexCount = static_cast<uint32_t>(
                        idx->sizeInBytes() / sizeof(uint16_t));
                    active->drawImageMesh(image,
                                          ImageSampler::LinearClamp(),
                                          ref_rcp(pos),
                                          ref_rcp(uvs),
                                          ref_rcp(idx),
                                          vertexCount,
                                          indexCount,
                                          blend,
                                          opacity,
                                          additiveness);
                }
                break;
            }
            case SerializeOp::makeImageMeshInstances:
            {
                uint64_t id = reader.readVarUint64();
                size_t count = static_cast<size_t>(reader.readVarUint64());
                meshInstances[id] = factory->makeImageMeshInstances(count);
                break;
            }
            case SerializeOp::setImageMeshInstancesData:
            {
                uint64_t id = reader.readVarUint64();
                size_t count = static_cast<size_t>(reader.readVarUint64());
                // An unknown id is dropped, but its payload is still read
                // so the stream stays in step.
                ImageMeshInstances* mi = find(meshInstances, id);
                Span<ImageMeshInstanceData> dst =
                    mi != nullptr ? mi->edit(count)
                                  : Span<ImageMeshInstanceData>();
                for (size_t i = 0; i < count; ++i)
                {
                    ImageMeshInstanceData instance;
                    float m[6];
                    for (int j = 0; j < 6; ++j)
                    {
                        m[j] = reader.readFloat32();
                    }
                    instance.transform =
                        Mat2D(m[0], m[1], m[2], m[3], m[4], m[5]);
                    instance.uvTranslate.x = reader.readFloat32();
                    instance.uvTranslate.y = reader.readFloat32();
                    instance.uvScale.x = reader.readFloat32();
                    instance.uvScale.y = reader.readFloat32();
                    instance.opacity = reader.readFloat32();
                    instance.additiveness = reader.readFloat32();
                    if (i < dst.size())
                    {
                        dst[i] = instance;
                    }
                }
                if (mi != nullptr)
                {
                    mi->endEdit();
                }
                break;
            }
            case SerializeOp::drawImageMeshInstanced:
            {
                RenderImage* image = find(images, reader.readVarUint64());
                RenderBuffer* pos = find(buffers, reader.readVarUint64());
                RenderBuffer* uvs = find(buffers, reader.readVarUint64());
                RenderBuffer* idx = find(buffers, reader.readVarUint64());
                ImageMeshInstances* mi =
                    find(meshInstances, reader.readVarUint64());
                if (image != nullptr && pos != nullptr && uvs != nullptr &&
                    idx != nullptr && mi != nullptr)
                {
                    uint32_t vertexCount = static_cast<uint32_t>(
                        pos->sizeInBytes() / (2 * sizeof(float)));
                    uint32_t indexCount = static_cast<uint32_t>(
                        idx->sizeInBytes() / sizeof(uint16_t));
                    active->drawImageMeshInstanced(image,
                                                   ImageSampler::LinearClamp(),
                                                   ref_rcp(pos),
                                                   ref_rcp(uvs),
                                                   ref_rcp(idx),
                                                   vertexCount,
                                                   indexCount,
                                                   ref_rcp(mi));
                }
                break;
            }
            case SerializeOp::makeRenderCanvas:
            {
                uint64_t id = reader.readVarUint64();
                uint32_t w = static_cast<uint32_t>(reader.readVarUint64());
                uint32_t h = static_cast<uint32_t>(reader.readVarUint64());
                // No allocation here: the host mints the target when the
                // content actually opens, on whatever device it replays
                // against.
                canvasSizes[id] = {w, h};
                break;
            }
            case SerializeOp::canvasContentBegin:
            {
                uint64_t id = reader.readVarUint64();
                uint32_t clearColor =
                    static_cast<uint32_t>(reader.readVarUint64());
                auto it = canvasSizes.find(id);
                if (it == canvasSizes.end())
                {
                    return false; // content for a canvas never declared
                }
                interrupted.push_back({id, active});
                rcp<RenderImage> image;
                Renderer* content =
                    hooks.onCanvasContentBegin
                        ? hooks.onCanvasContentBegin(id,
                                                     it->second.width,
                                                     it->second.height,
                                                     clearColor,
                                                     &image)
                        : nullptr;
                // A host with no offscreen target returns null. Its content is
                // parsed and dropped, and the composite that names this id
                // finds no image and draws nothing.
                if (content != nullptr)
                {
                    images[id] = std::move(image);
                }
                else
                {
                    // The raster was declined, so whatever the host may have
                    // allocated holds no content for this bracket. Drop any
                    // image it set, and any image a previous bracket left under
                    // this id, so the composite draws nothing rather than stale
                    // or uninitialized pixels.
                    images.erase(id);
                }
                active = content != nullptr ? content : &droppedContent;
                break;
            }
            case SerializeOp::canvasContentEnd:
            {
                uint64_t id = reader.readVarUint64();
                if (interrupted.empty())
                {
                    return false; // end without a matching begin
                }
                if (interrupted.back().id != id)
                {
                    // Ending a canvas the innermost bracket never opened.
                    // Honoring it would tell the host to close an unrelated
                    // canvas and hand the wrong renderer back to the ops that
                    // follow, so treat it as a malformed stream.
                    return false;
                }
                if (hooks.onCanvasContentEnd)
                {
                    hooks.onCanvasContentEnd(id);
                }
                active = interrupted.back().interruptedRenderer;
                interrupted.pop_back();
                break;
            }
            case SerializeOp::frame:
                if (hooks.onFrame)
                    hooks.onFrame();
                break;
            case SerializeOp::frameSize:
            {
                uint32_t w = static_cast<uint32_t>(reader.readVarUint64());
                uint32_t h = static_cast<uint32_t>(reader.readVarUint64());
                if (hooks.onFrameSize)
                    hooks.onFrameSize(w, h);
                break;
            }
            default:
                return false; // unknown opcode
        }
        if (reader.hasError())
            return false;
    }
    // A canvas left open means the stream was cut mid-bracket.
    return interrupted.empty();
}
