#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