#include "utils/serializing_factory.hpp"
#include "rive/decoders/bitmap_decoder.hpp"
#include "rive/core/binary_reader.hpp"
#include <cstring>
#include <stdlib.h>
#include <filesystem>
#include <inttypes.h>
#include <unordered_map>

using namespace rive;

// Threshold for floating point tests.
static const float epsilon = 0.001f;

enum class SerializeOp : unsigned char
{
    makeRenderBuffer = 0,
    makeLinearGradient = 1,
    makeRadialGradient = 2,
    makeRenderPath = 3,
    makeRenderPaint = 5,
    decodeImage = 6,
    save = 7,
    restore = 8,
    transform = 9,
    drawPath = 10,
    clipPath = 11,
    drawImage = 12,
    drawImageMesh = 13,

    // RenderBuffer
    setVertexBufferData = 14,
    setIndexBufferData = 15,

    // RenderPath
    addRawPath = 16,
    rewind = 17,
    fillRule = 18,

    // RenderPaint
    style = 20,
    color = 21,
    thickness = 22,
    join = 23,
    cap = 24,
    feather = 25,
    blendMode = 26,
    shader = 27,

    frame = 28,
    frameSize = 29,

};

static const char* opToName(SerializeOp op)
{
    switch (op)
    {
        case SerializeOp::makeRenderBuffer:
            return "makeRenderBuffer";
        case SerializeOp::makeLinearGradient:
            return "makeLinearGradient";
        case SerializeOp::makeRadialGradient:
            return "makeRadialGradient";
        case SerializeOp::makeRenderPath:
            return "makeRenderPath";
        case SerializeOp::makeRenderPaint:
            return "makeRenderPaint";
        case SerializeOp::decodeImage:
            return "decodeImage";
        case SerializeOp::save:
            return "save";
        case SerializeOp::restore:
            return "restore";
        case SerializeOp::transform:
            return "transform";
        case SerializeOp::drawPath:
            return "drawPath";
        case SerializeOp::clipPath:
            return "clipPath";
        case SerializeOp::drawImage:
            return "drawImage";
        case SerializeOp::drawImageMesh:
            return "drawImageMesh";

        // RenderBuffer
        case SerializeOp::setVertexBufferData:
            return "setVertexBufferData";
        case SerializeOp::setIndexBufferData:
            return "setIndexBufferData";

        // RenderPath
        case SerializeOp::addRawPath:
            return "addRawPath";
        case SerializeOp::rewind:
            return "rewind";
        case SerializeOp::fillRule:
            return "fillRule";

        // RenderPaint
        case SerializeOp::style:
            return "style";
        case SerializeOp::color:
            return "color";
        case SerializeOp::thickness:
            return "thickness";
        case SerializeOp::join:
            return "join";
        case SerializeOp::cap:
            return "cap";
        case SerializeOp::feather:
            return "feather";
        case SerializeOp::blendMode:
            return "blendMode";
        case SerializeOp::shader:
            return "shader";

        case SerializeOp::frame:
            return "frame";
        case SerializeOp::frameSize:
            return "frameSize";
    }
    return "???";
}

class SerializingRenderImage : public RenderImage
{
public:
    SerializingRenderImage(uint64_t id, uint32_t width, uint32_t height) :
        m_id(id)
    {
        m_Width = width;
        m_Height = height;
    }

    uint64_t id() const { return m_id; }

private:
    uint64_t m_id;
};

static void serializeRawPath(BinaryWriter* writer, const RawPath& path)
{
    auto verbs = path.verbs();
    auto points = path.points();
    writer->writeVarUint((uint64_t)verbs.size());
    for (auto verb : verbs)
    {
        writer->writeVarUint((uint64_t)verb);
    }
    writer->writeVarUint((uint64_t)points.size());
    for (auto point : points)
    {
        writer->writeFloat(point.x);
        writer->writeFloat(point.y);
    }
}

class SerializingRenderShader : public RenderShader
{
public:
    SerializingRenderShader(uint64_t id) : m_id(id) {}
    uint64_t id() const { return m_id; }

private:
    uint64_t m_id;
};

class SerializingRenderPaint : public RenderPaint
{
public:
    SerializingRenderPaint(BinaryWriter* writer, uint64_t id) :
        m_id(id), m_writer(writer)
    {
        m_writer->writeVarUint((uint32_t)SerializeOp::makeRenderPaint);
        m_writer->writeVarUint(m_id);
    }

    void color(unsigned int value) override
    {
        if (m_color == value)
        {
            return;
        }
        m_color = value;
        m_writer->writeVarUint((uint32_t)SerializeOp::color);
        m_writer->writeVarUint(m_id);
        m_writer->writeVarUint(m_color);
    }

    void style(RenderPaintStyle value) override
    {
        if (m_stroked == (value == RenderPaintStyle::stroke))
        {
            return;
        }
        m_stroked = value == RenderPaintStyle::stroke;
        m_writer->writeVarUint((uint32_t)SerializeOp::style);
        m_writer->writeVarUint(m_id);
        m_writer->writeVarUint((uint32_t)(m_stroked ? 0 : 1));
    }

    void thickness(float value) override
    {
        if (m_thickness == value)
        {
            return;
        }
        m_thickness = value;
        m_writer->writeVarUint((uint32_t)SerializeOp::thickness);
        m_writer->writeVarUint(m_id);
        m_writer->writeFloat(m_thickness);
    }

    void join(StrokeJoin value) override
    {
        if (m_join == value)
        {
            return;
        }
        m_join = value;
        m_writer->writeVarUint((uint32_t)SerializeOp::join);
        m_writer->writeVarUint(m_id);
        m_writer->writeVarUint((uint32_t)m_join);
    }

    void cap(StrokeCap value) override
    {
        if (m_cap == value)
        {
            return;
        }
        m_cap = value;
        m_writer->writeVarUint((uint32_t)SerializeOp::cap);
        m_writer->writeVarUint(m_id);
        m_writer->writeVarUint((uint32_t)m_cap);
    }

    void blendMode(BlendMode value) override
    {
        if (m_blendMode == value)
        {
            return;
        }
        m_blendMode = value;
        m_writer->writeVarUint((uint32_t)SerializeOp::blendMode);
        m_writer->writeVarUint(m_id);
        m_writer->writeVarUint((uint32_t)m_blendMode);
    }

    void shader(rcp<RenderShader> shader) override
    {
        if (m_shader == shader)
        {
            return;
        }
        m_shader = shader;
        m_writer->writeVarUint((uint32_t)SerializeOp::shader);
        m_writer->writeVarUint(m_id);
        m_writer->writeVarUint(
            shader == nullptr
                ? 0
                : static_cast<SerializingRenderShader*>(shader.get())->id());
    }
    void invalidateStroke() override {}
    void feather(float value) override
    {
        if (m_feather == value)
        {
            return;
        }
        m_feather = value;
        m_writer->writeVarUint((uint32_t)SerializeOp::feather);
        m_writer->writeVarUint(m_id);
        m_writer->writeFloat(m_feather);
    }

    uint64_t id() const { return m_id; }

private:
    uint64_t m_id;
    BinaryWriter* m_writer;
    rcp<RenderShader> m_shader;

    unsigned int m_color = 0xFF000000;
    float m_thickness = 1;
    StrokeJoin m_join = StrokeJoin::miter;
    StrokeCap m_cap = StrokeCap::butt;
    float m_feather = 0;
    BlendMode m_blendMode = BlendMode::srcOver;
    bool m_stroked = false;
};

class SerializingRenderPath : public RenderPath
{
public:
    void rewind() override
    {
        m_writer->writeVarUint((uint32_t)SerializeOp::rewind);
        m_writer->writeVarUint(m_id);
    }

    void fillRule(FillRule value) override
    {
        if (m_fillRule == value)
        {
            return;
        }
        m_fillRule = value;
        m_writer->writeVarUint((uint32_t)SerializeOp::fillRule);
        m_writer->writeVarUint(m_id);
        m_writer->writeVarUint((uint64_t)value);
    }

    void addPath(CommandPath* path, const Mat2D& transform) override
    {
        RIVE_UNREACHABLE();
    }
    void addRenderPath(RenderPath* path, const Mat2D& transform) override
    {
        RIVE_UNREACHABLE();
    }

    void moveTo(float x, float y) override { RIVE_UNREACHABLE(); }
    void lineTo(float x, float y) override { RIVE_UNREACHABLE(); }
    void cubicTo(float ox, float oy, float ix, float iy, float x, float y)
        override
    {
        RIVE_UNREACHABLE();
    }
    void close() override { RIVE_UNREACHABLE(); }

    void addRawPath(const RawPath& path) override
    {
        m_rawPath.addPath(path, nullptr);

        m_writer->writeVarUint((uint32_t)SerializeOp::addRawPath);
        m_writer->writeVarUint(m_id);
        serializeRawPath(m_writer, path);
    }

    SerializingRenderPath(BinaryWriter* writer, uint64_t id) :
        m_id(id), m_writer(writer)
    {
        m_writer->writeVarUint((uint32_t)SerializeOp::makeRenderPath);
        m_writer->writeVarUint(m_id);
    }

    SerializingRenderPath(BinaryWriter* writer,
                          uint64_t id,
                          const RawPath& path,
                          FillRule fillRule) :
        m_id(id), m_fillRule(fillRule), m_rawPath(path), m_writer(writer)
    {
        m_writer->writeVarUint((uint32_t)SerializeOp::makeRenderPath);
        m_writer->writeVarUint(m_id);
        this->fillRule(fillRule);
        addRawPath(path);
    }

    uint64_t id() const { return m_id; }

private:
    uint64_t m_id;
    FillRule m_fillRule = FillRule::nonZero;
    RawPath m_rawPath;
    BinaryWriter* m_writer;
};

class SerializingRenderBuffer : public RenderBuffer
{
public:
    SerializingRenderBuffer(BinaryWriter* writer,
                            uint64_t id,
                            RenderBufferType type,
                            RenderBufferFlags flags,
                            size_t sizeInBytes) :
        RenderBuffer(type, flags, sizeInBytes),
        m_writer(writer),
        m_bytes(sizeInBytes),
        m_id(id)
    {
        m_writer->writeVarUint((uint32_t)SerializeOp::makeRenderBuffer);
        m_writer->writeVarUint(m_id);
        m_writer->writeVarUint((uint64_t)sizeInBytes);
        m_writer->writeVarUint((uint32_t)type);
        m_writer->writeVarUint((uint32_t)flags);
    }

    uint64_t id() const { return m_id; }
    void* onMap() override { return m_bytes.data(); }
    void onUnmap() override
    {
        switch (type())
        {
            case RenderBufferType::index:
                m_writer->writeVarUint(
                    (uint32_t)SerializeOp::setIndexBufferData);
                break;
            case RenderBufferType::vertex:
                m_writer->writeVarUint(
                    (uint32_t)SerializeOp::setVertexBufferData);
                break;
            default:
                RIVE_UNREACHABLE();
        }
        m_writer->writeVarUint(m_id);
        switch (type())
        {
            case RenderBufferType::vertex:
            {
                auto count = m_bytes.size() / sizeof(float);
                auto floatBuffer = reinterpret_cast<float*>(m_bytes.data());
                for (size_t i = 0; i < count; i++)
                {
                    m_writer->writeFloat(floatBuffer[i]);
                }
                break;
            }
            case RenderBufferType::index:
            {
                auto count = m_bytes.size() / sizeof(uint16_t);
                auto shortBuffer = reinterpret_cast<uint16_t*>(m_bytes.data());
                for (size_t i = 0; i < count; i++)
                {
                    m_writer->writeVarUint((uint32_t)shortBuffer[i]);
                }
                break;
            }
        }
    }

private:
    BinaryWriter* m_writer;
    std::vector<uint8_t> m_bytes;
    uint64_t m_id;
};

rcp<RenderBuffer> SerializingFactory::makeRenderBuffer(RenderBufferType type,
                                                       RenderBufferFlags flags,
                                                       size_t size)
{
    return make_rcp<SerializingRenderBuffer>(&m_writer,
                                             m_renderBufferId++,
                                             type,
                                             flags,
                                             size);
}

rcp<RenderShader> SerializingFactory::makeLinearGradient(
    float sx,
    float sy,
    float ex,
    float ey,
    const ColorInt colors[], // [count]
    const float stops[],     // [count]
    size_t count)
{
    auto id = m_renderShaderId++;
    m_writer.writeVarUint((uint32_t)SerializeOp::makeLinearGradient);
    m_writer.writeVarUint(id);
    m_writer.writeVarUint((uint64_t)count);
    for (auto i = 0; i < count; i++)
    {
        m_writer.writeVarUint(colors[i]);
        m_writer.writeFloat(stops[i]);
    }
    m_writer.writeFloat(sx);
    m_writer.writeFloat(sy);
    m_writer.writeFloat(ex);
    m_writer.writeFloat(ey);

    return make_rcp<SerializingRenderShader>(id);
}

rcp<RenderShader> SerializingFactory::makeRadialGradient(
    float cx,
    float cy,
    float radius,
    const ColorInt colors[], // [count]
    const float stops[],     // [count]
    size_t count)
{
    auto id = m_renderShaderId++;
    m_writer.writeVarUint((uint32_t)SerializeOp::makeRadialGradient);
    m_writer.writeVarUint(id);
    m_writer.writeVarUint((uint64_t)count);
    for (auto i = 0; i < count; i++)
    {
        m_writer.writeVarUint(colors[i]);
        m_writer.writeFloat(stops[i]);
    }
    m_writer.writeFloat(cx);
    m_writer.writeFloat(cy);
    m_writer.writeFloat(radius);

    return make_rcp<SerializingRenderShader>(id);
}

rcp<RenderPath> SerializingFactory::makeRenderPath(RawPath& rawPath,
                                                   FillRule fillRule)
{
    return make_rcp<SerializingRenderPath>(&m_writer,
                                           m_renderPathId++,
                                           rawPath,
                                           fillRule);
}

rcp<RenderPath> SerializingFactory::makeEmptyRenderPath()
{
    return make_rcp<SerializingRenderPath>(&m_writer, m_renderPathId++);
}

rcp<RenderPaint> SerializingFactory::makeRenderPaint()
{
    return make_rcp<SerializingRenderPaint>(&m_writer, m_renderPaintId++);
}

rcp<RenderImage> SerializingFactory::decodeImage(Span<const uint8_t> data)
{
    auto id = m_renderImageId++;
    m_writer.writeVarUint((uint32_t)SerializeOp::decodeImage);
    m_writer.writeVarUint(id);
    m_writer.writeVarUint((uint64_t)data.size());
    m_writer.write(data.data(), data.size());

    auto bitmap = Bitmap::decode(data.data(), data.size());
    if (!bitmap)
    {
        return nullptr;
    }

    return make_rcp<SerializingRenderImage>(id,
                                            bitmap->width(),
                                            bitmap->height());
}

class SerializingRenderer : public Renderer
{
public:
    SerializingRenderer(BinaryWriter* writer) : m_writer(writer) {}

    void save() override
    {
        m_writer->writeVarUint((uint32_t)SerializeOp::save);
    }
    void restore() override
    {
        m_writer->writeVarUint((uint32_t)SerializeOp::restore);
    }
    void transform(const Mat2D& mat) override
    {
        m_writer->writeVarUint((uint32_t)SerializeOp::transform);
        for (int i = 0; i < 6; i++)
        {
            m_writer->writeFloat(mat[i]);
        }
    }

    void drawPath(RenderPath* path, RenderPaint* paint) override
    {
        m_writer->writeVarUint((uint32_t)SerializeOp::drawPath);
        m_writer->writeVarUint(static_cast<SerializingRenderPath*>(path)->id());
        m_writer->writeVarUint(
            static_cast<SerializingRenderPaint*>(paint)->id());
    }

    void clipPath(RenderPath* path) override
    {
        m_writer->writeVarUint((uint32_t)SerializeOp::clipPath);
        m_writer->writeVarUint(static_cast<SerializingRenderPath*>(path)->id());
    }

    virtual void drawImage(const RenderImage* image,
                           ImageSampler samplerOptions,
                           BlendMode blendMode,
                           float opacity) override
    {
        m_writer->writeVarUint((uint32_t)SerializeOp::drawImage);
        m_writer->writeVarUint(
            static_cast<const SerializingRenderImage*>(image)->id());
        m_writer->writeVarUint((uint32_t)blendMode);
        m_writer->writeFloat(opacity);
    }

    virtual void drawImageMesh(const RenderImage* image,
                               ImageSampler samplerOptions,
                               rcp<RenderBuffer> positions,
                               rcp<RenderBuffer> uvs,
                               rcp<RenderBuffer> indices,
                               uint32_t vertexCount,
                               uint32_t indexCount,
                               BlendMode blendMode,
                               float opacity) override
    {
        m_writer->writeVarUint((uint32_t)SerializeOp::drawImageMesh);
        m_writer->writeVarUint(
            static_cast<const SerializingRenderImage*>(image)->id());
        m_writer->writeVarUint((uint32_t)blendMode);
        m_writer->writeFloat(opacity);
        m_writer->writeVarUint(
            static_cast<SerializingRenderBuffer*>(positions.get())->id());
        m_writer->writeVarUint(
            static_cast<SerializingRenderBuffer*>(uvs.get())->id());
        m_writer->writeVarUint(
            static_cast<SerializingRenderBuffer*>(indices.get())->id());
    }

private:
    BinaryWriter* m_writer;
};

SerializingFactory::SerializingFactory() : m_writer(&m_buffer)
{
    m_writer.write((const uint8_t*)"SRIV", 4);
    m_writer.writeVarUint((uint32_t)1);
}

std::unique_ptr<Renderer> SerializingFactory::makeRenderer()
{
    return rivestd::make_unique<SerializingRenderer>(&m_writer);
}

void SerializingFactory::addFrame()
{
    m_writer.writeVarUint((uint32_t)SerializeOp::frame);
}

void SerializingFactory::frameSize(uint32_t width, uint32_t height)
{
    m_writer.writeVarUint((uint32_t)SerializeOp::frameSize);
    m_writer.writeVarUint(width);
    m_writer.writeVarUint(height);
}

void SerializingFactory::save(const char* filename)
{
    FILE* fp = fopen(filename, "wb");
    fwrite(m_buffer.data(), 1, m_buffer.size(), fp);
    fclose(fp);
}

void SerializingFactory::saveTarnished(const char* filename)
{
    auto path = std::string("silvers/tarnished/");
    if (!std::filesystem::exists(path))
    {
        if (!std::filesystem::create_directories(path))
        {
            fprintf(stderr, "failed to create directory %s\n", path.c_str());
        }
    }
    auto fullFileName = path + std::string(filename) + std::string(".sriv");
    save(fullFileName.c_str());
}

static bool varUintMatches(uint64_t op,
                           std::string name,
                           BinaryReader& readerA,
                           BinaryReader& readerB,
                           uint64_t* value = nullptr)
{
    auto valueA = readerA.readVarUint64();
    auto valueB = readerB.readVarUint64();
    if (valueA != valueB)
    {
        fprintf(stderr,
                "%s for %s doesn't match %" PRIu64 " != %" PRIu64 "\n",
                name.c_str(),
                opToName((SerializeOp)op),
                valueA,
                valueB);
        return false;
    }
    if (value != nullptr)
    {
        *value = valueA;
    }
    return true;
}

static bool bytesMatches(uint64_t op,
                         std::string name,
                         uint64_t size,
                         BinaryReader& readerA,
                         BinaryReader& readerB)
{
    for (int i = 0; i < size; i++)
    {
        auto valueA = readerA.readByte();
        auto valueB = readerB.readByte();
        if (valueA != valueB)
        {
            fprintf(stderr,
                    "%s [%i] for %s doesn't match %hhu != %hhu\n",
                    name.c_str(),
                    i,
                    opToName((SerializeOp)op),
                    valueA,
                    valueB);
            return false;
        }
    }
    return true;
}

static bool floatMatches(uint64_t op,
                         std::string name,
                         BinaryReader& readerA,
                         BinaryReader& readerB,
                         float* value = nullptr)
{
    auto valueA = readerA.readFloat32();
    auto valueB = readerB.readFloat32();
    if (std::abs(valueA - valueB) > epsilon)
    {
        fprintf(stderr,
                "%s for %s doesn't match %f != %f\n",
                name.c_str(),
                opToName((SerializeOp)op),
                valueA,
                valueB);
        return false;
    }
    if (value != nullptr)
    {
        *value = valueA;
    }
    return true;
}

static bool shortMatches(uint64_t op,
                         std::string name,
                         BinaryReader& readerA,
                         BinaryReader& readerB,
                         uint16_t* value = nullptr)
{
    auto valueA = readerA.readUint16();
    auto valueB = readerB.readUint16();
    if (valueA != valueB)
    {
        fprintf(stderr,
                "%s for %s doesn't match %i != %i\n",
                name.c_str(),
                opToName((SerializeOp)op),
                valueA,
                valueB);
        return false;
    }
    if (value != nullptr)
    {
        *value = valueA;
    }
    return true;
}

static bool vec2DMatches(uint64_t op,
                         std::string name,
                         BinaryReader& readerA,
                         BinaryReader& readerB,
                         Vec2D* value = nullptr)
{
    auto ax = readerA.readFloat32();
    auto ay = readerA.readFloat32();

    auto bx = readerB.readFloat32();
    auto by = readerB.readFloat32();

    // if (ax != bx || ay != by)
    if (rive::Vec2D::distance(Vec2D(ax, ay), Vec2D(bx, by)) > epsilon)
    {
        fprintf(stderr,
                "%s for %s doesn't match (%f, %f) != (%f, %f)\n",
                name.c_str(),
                opToName((SerializeOp)op),
                ax,
                ay,
                bx,
                by);
        return false;
    }
    if (value != nullptr)
    {
        *value = Vec2D(ax, ay);
    }
    return true;
}

static bool gradientMatches(uint64_t op,
                            std::string name,
                            BinaryReader& readerA,
                            BinaryReader& readerB,
                            Vec2D* value = nullptr)
{
    if (!varUintMatches(op,
                        std::string("make_") + name + std::string("_id"),
                        readerA,
                        readerB))
    {
        return false;
    }
    uint64_t count = 0;
    if (!varUintMatches(op,
                        std::string("make_") + name + std::string("_count"),
                        readerA,
                        readerB,
                        &count))
    {
        return false;
    }
    for (size_t i = 0; i < count; i++)
    {
        std::string colorName = std::string("make_") + name +
                                std::string("_color_") + std::to_string(i);
        if (!varUintMatches(op, colorName, readerA, readerB))
        {
            return false;
        }
        std::string stopName = std::string("make_") + name +
                               std::string("_stop_") + std::to_string(i);
        if (!floatMatches(op, stopName, readerA, readerB))
        {
            return false;
        }
    }
    return true;
}

bool advancedMatch(std::vector<uint8_t>& fileA, std::vector<uint8_t>& fileB)
{
    BinaryReader readerA(fileA);
    BinaryReader readerB(fileB);
    if (readerA.readByte() != 'S' || readerA.readByte() != 'R' ||
        readerA.readByte() != 'I' || readerA.readByte() != 'V')
    {
        fprintf(stderr, "advancedMatch: invalid header A\n");
        return false;
    }
    if (readerB.readByte() != 'S' || readerB.readByte() != 'R' ||
        readerB.readByte() != 'I' || readerB.readByte() != 'V')
    {
        fprintf(stderr, "advancedMatch: invalid header B\n");
        return false;
    }

    if (readerA.readVarUint64() != 1 || readerB.readVarUint64() != 1)
    {
        fprintf(stderr, "advancedMatch: invalid version\n");
        return false;
    }
    std::unordered_map<uint64_t, uint64_t> renderBufferSizes;
    while (!readerA.reachedEnd())
    {
        if (readerB.reachedEnd())
        {
            fprintf(stderr, "generated file is shorter.\n");
            return false;
        }
        auto opA = readerA.readVarUint64();
        auto opB = readerB.readVarUint64();
        if (opA != opB)
        {
            fprintf(stderr,
                    "expected %s but got %s\n",
                    opToName((SerializeOp)opA),
                    opToName((SerializeOp)opB));
        }
        switch ((SerializeOp)opA)
        {
            case SerializeOp::makeRenderBuffer:
            {
                uint64_t id = 0;
                uint64_t size = 0;
                if (!varUintMatches(opA,
                                    "make_renderbuffer_id",
                                    readerA,
                                    readerB,
                                    &id))
                {
                    return false;
                }
                if (!varUintMatches(opA,
                                    "make_renderbuffer_size",
                                    readerA,
                                    readerB,
                                    &size))
                {
                    return false;
                }
                if (!varUintMatches(opA,
                                    "make_renderbuffer_flags",
                                    readerA,
                                    readerB))
                {
                    return false;
                }
                renderBufferSizes[id] = size;
                break;
            }
            case SerializeOp::makeLinearGradient:
                if (!gradientMatches(opA, "lineargradient", readerA, readerB))
                {
                    return false;
                }
                if (!vec2DMatches(opA,
                                  "make_lineargradient_start",
                                  readerA,
                                  readerB))
                {
                    return false;
                }
                if (!vec2DMatches(opA,
                                  "make_lineargradient_end",
                                  readerA,
                                  readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::makeRadialGradient:
                if (!gradientMatches(opA, "lineargradient", readerA, readerB))
                {
                    return false;
                }
                if (!vec2DMatches(opA,
                                  "make_lineargradient_center",
                                  readerA,
                                  readerB))
                {
                    return false;
                }
                if (!floatMatches(opA,
                                  "make_lineargradient_radius",
                                  readerA,
                                  readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::makeRenderPath:
                if (!varUintMatches(opA,
                                    "make_renderpath_id",
                                    readerA,
                                    readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::makeRenderPaint:
                if (!varUintMatches(opA,
                                    "make_renderpaint_id",
                                    readerA,
                                    readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::decodeImage:
            {
                if (!varUintMatches(opA, "decodeimage_id", readerA, readerB))
                {
                    return false;
                }
                uint64_t size = 0;
                if (!varUintMatches(opA,
                                    "decodeimage_size",
                                    readerA,
                                    readerB,
                                    &size))
                {
                    return false;
                }
                if (!bytesMatches(opA,
                                  "decodeimage_bytes",
                                  size,
                                  readerA,
                                  readerB))
                {
                    return false;
                }
                break;
            }
            case SerializeOp::save:
                break;
            case SerializeOp::restore:
                break;
            case SerializeOp::transform:
                for (int i = 0; i < 6; i++)
                {
                    if (!floatMatches(opA,
                                      std::string("transform[") +
                                          std::to_string(i) + std::string("]"),
                                      readerA,
                                      readerB))
                    {
                        return false;
                    }
                }
                break;
            case SerializeOp::drawPath:
                if (!varUintMatches(opA, "drawpath_id", readerA, readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA, "drawpath_paint_id", readerA, readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::clipPath:
                if (!varUintMatches(opA, "clippath_id", readerA, readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::drawImage:
                if (!varUintMatches(opA, "drawimage_id", readerA, readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA,
                                    "drawimage_blendmode",
                                    readerA,
                                    readerB))
                {
                    return false;
                }
                if (!floatMatches(opA, "drawimage_opacity", readerA, readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::drawImageMesh:
                if (!varUintMatches(opA, "drawimagemesh_id", readerA, readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA,
                                    "drawimagemesh_blendmode",
                                    readerA,
                                    readerB))
                {
                    return false;
                }
                if (!floatMatches(opA,
                                  "drawimagemesh_opacity",
                                  readerA,
                                  readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA,
                                    "drawimagemesh_vertex_id",
                                    readerA,
                                    readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA,
                                    "drawimagemesh_uv_id",
                                    readerA,
                                    readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA,
                                    "drawimagemesh_index_id",
                                    readerA,
                                    readerB))
                {
                    return false;
                }
                break;

            case SerializeOp::setVertexBufferData:
            {
                uint64_t id = 0;
                if (!varUintMatches(opA,
                                    "setvertexbufferdata_id",
                                    readerA,
                                    readerB,
                                    &id))
                {
                    return false;
                }
                if (renderBufferSizes.find(id) == renderBufferSizes.end())
                {
                    fprintf(stderr,
                            "could not find render buffer with id: %" PRIu64
                            "\n",
                            id);
                    return false;
                }
                uint64_t size = renderBufferSizes[id];
                uint64_t floatCount = size / sizeof(float);
                for (int i = 0; i < floatCount; i++)
                {
                    if (!floatMatches(opA,
                                      std::string("setvertexbufferdata_[") +
                                          std::to_string(i) + std::string("]"),
                                      readerA,
                                      readerB))
                    {
                        return false;
                    }
                }
                break;
            }
            case SerializeOp::setIndexBufferData:
            {
                uint64_t id = 0;
                if (!varUintMatches(opA,
                                    "setindexbufferdata_id",
                                    readerA,
                                    readerB,
                                    &id))
                {
                    return false;
                }
                if (renderBufferSizes.find(id) == renderBufferSizes.end())
                {
                    fprintf(stderr,
                            "could not find render buffer with id: %" PRIu64
                            "\n",
                            id);
                    return false;
                }
                uint64_t size = renderBufferSizes[id];
                uint64_t shortCount = size / sizeof(uint16_t);
                for (int i = 0; i < shortCount; i++)
                {
                    if (!shortMatches(opA,
                                      std::string("setindexbufferdata_[") +
                                          std::to_string(i) + std::string("]"),
                                      readerA,
                                      readerB))
                    {
                        return false;
                    }
                }
                break;
            }

            // RenderPath
            case SerializeOp::addRawPath:
            {
                uint64_t verbCount = 0;
                uint64_t pointCount = 0;
                if (!varUintMatches(opA, "addrawpath_id", readerA, readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA,
                                    "addrawpath_verb_count",
                                    readerA,
                                    readerB,
                                    &verbCount))
                {
                    return false;
                }
                for (int i = 0; i < verbCount; i++)
                {
                    if (!varUintMatches(opA,
                                        std::string("addrawpath_verb[") +
                                            std::to_string(i) +
                                            std::string("]"),
                                        readerA,
                                        readerB))
                    {
                        return false;
                    }
                }
                if (!varUintMatches(opA,
                                    "addrawpath_point_count",
                                    readerA,
                                    readerB,
                                    &pointCount))
                {
                    return false;
                }
                for (int i = 0; i < pointCount; i++)
                {
                    if (!vec2DMatches(opA,
                                      std::string("addrawpath_point[") +
                                          std::to_string(i) + std::string("]"),
                                      readerA,
                                      readerB))
                    {
                        return false;
                    }
                }
            }
            break;
            case SerializeOp::rewind:
                if (!varUintMatches(opA, "rewind_path_id", readerA, readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::fillRule:
                if (!varUintMatches(opA, "fillrule_path_id", readerA, readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA, "fillrule_value", readerA, readerB))
                {
                    return false;
                }
                break;

            // RenderPaint
            case SerializeOp::style:
                if (!varUintMatches(opA, "style_paint_id", readerA, readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA, "style_value", readerA, readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::color:
                if (!varUintMatches(opA, "color_paint_id", readerA, readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA, "color_value", readerA, readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::thickness:
                if (!varUintMatches(opA,
                                    "thickness_paint_id",
                                    readerA,
                                    readerB))
                {
                    return false;
                }
                if (!floatMatches(opA, "thickness_value", readerA, readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::join:
                if (!varUintMatches(opA, "join_paint_id", readerA, readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA, "join_value", readerA, readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::cap:
                if (!varUintMatches(opA, "cap_paint_id", readerA, readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA, "cap_value", readerA, readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::feather:
                if (!varUintMatches(opA, "feather_paint_id", readerA, readerB))
                {
                    return false;
                }
                if (!floatMatches(opA, "feather_value", readerA, readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::blendMode:
                if (!varUintMatches(opA,
                                    "blendmode_paint_id",
                                    readerA,
                                    readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA, "blendmode_value", readerA, readerB))
                {
                    return false;
                }
                break;
            case SerializeOp::shader:
                if (!varUintMatches(opA,
                                    "setgradient_paint_id",
                                    readerA,
                                    readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA, "setgradient_value", readerA, readerB))
                {
                    return false;
                }
                break;

            case SerializeOp::frame:
                break;
            case SerializeOp::frameSize:
                if (!varUintMatches(opA, "framesize_width", readerA, readerB))
                {
                    return false;
                }
                if (!varUintMatches(opA, "framesize_height", readerA, readerB))
                {
                    return false;
                }
        }
    }
    if (!readerB.reachedEnd())
    {
        fprintf(stderr, "generated file is longer, otherwise matches.\n");
        return false;
    }
    // for (size_t i = 0; i < length; i++)
    // {
    //     if (fileA[i] != fileB[i])
    //     {
    //         fprintf(stderr,
    //                 "SerializingFactory::matches - %s buffer did not match "
    //                 "generated one.\n",
    //                 filename);

    //         return false;
    //     }
    // }
    return true;
}

bool SerializingFactory::matches(const char* filename)
{
    auto fullFileName =
        std::string("silvers/") + std::string(filename) + std::string(".sriv");
    const char* rebaseline = getenv("REBASELINE_SILVERS");
    if (rebaseline != nullptr)
    {
        save(fullFileName.c_str());
        return true;
    }

    FILE* fp = fopen(fullFileName.c_str(), "rb");
    if (fp == nullptr)
    {
        fprintf(stderr,
                "SerializingFactory::matches - %s is missing\n",
                fullFileName.c_str());
        return false;
    }
    fseek(fp, 0, SEEK_END);
    const size_t length = ftell(fp);
    if (m_buffer.size() != length)
    {
        fprintf(stderr,
                "SerializingFactory::matches - %s size differs from generated "
                "one %zu != %zu.\n",
                filename,
                m_buffer.size(),
                length);
        fclose(fp);
        saveTarnished(filename);
        return false;
    }

    fseek(fp, 0, SEEK_SET);
    std::vector<uint8_t> existing(length);
    if (fread(existing.data(), 1, length, fp) != length)
    {
        fprintf(stderr,
                "SerializingFactory::matches - %s could not be read.\n",
                filename);
        return false;
    }
    fclose(fp);

    if (!advancedMatch(existing, m_buffer))
    {
        saveTarnished(filename);
        return false;
    }
    return true;
}
