#ifdef RIVE_RENDERER_TESS
#include "viewer/tess/bitmap_decoder.hpp"
#include <vector>

Bitmap::Bitmap(uint32_t width,
               uint32_t height,
               PixelFormat pixelFormat,
               std::unique_ptr<const uint8_t[]> bytes) :
    m_Width(width), m_Height(height), m_PixelFormat(pixelFormat), m_Bytes(std::move(bytes))
{}

Bitmap::Bitmap(uint32_t width, uint32_t height, PixelFormat pixelFormat, const uint8_t* bytes) :
    Bitmap(width, height, pixelFormat, std::unique_ptr<const uint8_t[]>(bytes))
{}

size_t Bitmap::bytesPerPixel(PixelFormat format) const
{
    switch (format)
    {
        case PixelFormat::R:
            return 1;
        case PixelFormat::RGB:
            return 3;
        case PixelFormat::RGBA:
            return 4;
    }
}

size_t Bitmap::byteSize(PixelFormat format) const
{
    return m_Width * m_Height * bytesPerPixel(format);
}

size_t Bitmap::byteSize() const { return byteSize(m_PixelFormat); }

std::unique_ptr<Bitmap> DecodePng(rive::Span<const uint8_t> bytes);
std::unique_ptr<Bitmap> DecodeJpeg(rive::Span<const uint8_t> bytes) { return nullptr; }
std::unique_ptr<Bitmap> DecodeWebP(rive::Span<const uint8_t> bytes) { return nullptr; }

using BitmapDecoder = std::unique_ptr<Bitmap> (*)(rive::Span<const uint8_t> bytes);
struct ImageFormat
{
    const char* name;
    std::vector<const uint8_t> fingerprint;
    BitmapDecoder decodeImage;
};

std::unique_ptr<Bitmap> Bitmap::decode(rive::Span<const uint8_t> bytes)
{
    static ImageFormat decoders[] = {
        {
            "png",
            {0x89, 0x50, 0x4E, 0x47},
            DecodePng,
        },
        {
            "jpeg",
            {0xFF, 0xD8, 0xFF},
            DecodeJpeg,
        },
        {
            "webp",
            {0x52, 0x49, 0x46},
            DecodeWebP,
        },
    };

    for (auto recognizer : decoders)
    {
        auto& fingerprint = recognizer.fingerprint;

        // Immediately discard decoders with fingerprints that are longer than
        // the file buffer.
        if (recognizer.fingerprint.size() > bytes.size())
        {
            continue;
        }

        // If the fingerprint doesn't match, discrd this decoder. These are all bytes so .size() is
        // fine here.
        if (std::memcmp(fingerprint.data(), bytes.data(), fingerprint.size()) != 0)
        {
            continue;
        }

        auto bitmap = recognizer.decodeImage(bytes);
        if (!bitmap)
        {
            fprintf(stderr, "Bitmap::decode - failed to decode a %s.\n", recognizer.name);
        }
        return bitmap;
    }
    return nullptr;
}

void Bitmap::pixelFormat(PixelFormat format)
{
    if (format == m_PixelFormat)
    {
        return;
    }
    auto nextByteSize = byteSize(format);
    auto nextBytes = std::make_unique<uint8_t[]>(nextByteSize);

    auto fromBytesPerPixel = bytesPerPixel(m_PixelFormat);
    auto toBytesPerPixel = bytesPerPixel(format);
    int writeIndex = 0;
    int readIndex = 0;
    for (int i = 0; i < m_Width * m_Height; i++)
    {
        for (int j = 0; j < toBytesPerPixel; j++)
        {
            nextBytes[writeIndex++] = j < fromBytesPerPixel ? m_Bytes[readIndex++] : 255;
        }
    }

    m_Bytes = std::move(nextBytes);
    m_PixelFormat = format;
}
#endif