/*
 * Copyright 2023 Rive
 */

#include "rive/decoders/bitmap_decoder.hpp"
#include "rive/rive_types.hpp"
#include <stdio.h>
#include <string.h>
#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::RGB:
            return 3;
        case PixelFormat::RGBA:
            return 4;
    }
    RIVE_UNREACHABLE();
}

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(const uint8_t bytes[], size_t byteCount);
std::unique_ptr<Bitmap> DecodeJpeg(const uint8_t bytes[], size_t byteCount);
std::unique_ptr<Bitmap> DecodeWebP(const uint8_t bytes[], size_t byteCount) { return nullptr; }

using BitmapDecoder = std::unique_ptr<Bitmap> (*)(const uint8_t bytes[], size_t byteCount);
struct ImageFormat
{
    const char* name;
    std::vector<uint8_t> fingerprint;
    BitmapDecoder decodeImage;
};

std::unique_ptr<Bitmap> Bitmap::decode(const uint8_t bytes[], size_t byteCount)
{
    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() > byteCount)
        {
            continue;
        }

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

        auto bitmap = recognizer.decodeImage(bytes, byteCount);
        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::unique_ptr<uint8_t[]>(new uint8_t[nextByteSize]);

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

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