// Adapted from libjpeg-turbo's example:
// https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/example.c
#include "rive/decoders/bitmap_decoder.hpp"

#include "jpeglib.h"
#include "jerror.h"

#include <setjmp.h>
#include <algorithm>
#include <cassert>
#include <string.h>

struct my_error_mgr
{
    struct jpeg_error_mgr pub;
    jmp_buf setjmp_buffer;
};

typedef struct my_error_mgr* my_error_ptr;

void my_error_exit(j_common_ptr cinfo)
{
    // cinfo.err really points to a my_error_mgr struct, so coerce pointer
    my_error_ptr myerr = (my_error_ptr)cinfo->err;

    // Always display the message.
    // We could postpone this until after returning, if we chose.
    (*cinfo->err->output_message)(cinfo);

    // Return control to the setjmp point
    longjmp(myerr->setjmp_buffer, 1);
}

std::unique_ptr<Bitmap> DecodeJpeg(const uint8_t bytes[], size_t byteCount)
{
    struct jpeg_decompress_struct cinfo;
    struct my_error_mgr jerr;

    JSAMPARRAY buffer = nullptr;
    std::unique_ptr<const uint8_t[]> pixelBuffer;
    int row_stride;

    // Step 1: allocate and initialize JPEG decompression object.

    // We set up the normal JPEG error routines, then override error_exit.
    cinfo.err = jpeg_std_error(&jerr.pub);
    jerr.pub.error_exit = my_error_exit;
    // Establish the setjmp return context for my_error_exit to use.
    if (setjmp(jerr.setjmp_buffer))
    {
        // If we get here, the JPEG code has signaled an error.
        // We need to clean up the JPEG object, close the input file, and
        // return.
        jpeg_destroy_decompress(&cinfo);
        return nullptr;
    }

    // Now we can initialize the JPEG decompression object.
    jpeg_create_decompress(&cinfo);

    // Step 2: specify data source
    jpeg_mem_src(&cinfo, bytes, byteCount);

    // Step 3: read file parameters with jpeg_read_header()

    jpeg_read_header(&cinfo, TRUE);

    // Step 4: set parameters for decompression

    // always want 8 bit RGB
    cinfo.data_precision = 8;
    cinfo.out_color_space = JCS_RGB;

    // Step 5: Start decompressor
    jpeg_start_decompress(&cinfo);

    /// Api worked as expected and gave us correct format even for jpeg 12 or 16
    assert(cinfo.data_precision == 8);
    assert(cinfo.output_components == 3);

    size_t pixelBufferSize = static_cast<size_t>(cinfo.output_width) *
                             static_cast<size_t>(cinfo.output_height) *
                             static_cast<size_t>(cinfo.output_components);
    pixelBuffer = std::make_unique<uint8_t[]>(pixelBufferSize);

    uint8_t* pixelWriteBuffer = (uint8_t*)pixelBuffer.get();
    const uint8_t* pixelWriteBufferEnd = pixelWriteBuffer + pixelBufferSize;

    // Samples per row in output buffer
    row_stride = cinfo.output_width * cinfo.output_components;
    // Make a one-row-high sample array that will go away when done with image
    buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo,
                                        JPOOL_IMAGE,
                                        row_stride,
                                        1);

    // Step 6: while (scan lines remain to be read)
    //           jpeg_read_scanlines(...);

    // Here we use the library's state variable cinfo->output_scanline as the
    // loop counter, so that we don't have to keep track ourselves.
    //
    while (cinfo.output_scanline < cinfo.output_height)
    {
        // jpeg_read_scanlines expects an array of pointers to scanlines.
        // Here the array is only one element long, but you could ask for
        // more than one scanline at a time if that's more convenient.
        jpeg_read_scanlines(&cinfo, buffer, 1);

        if (pixelWriteBuffer + row_stride > pixelWriteBufferEnd)
        {
            // memcpy would cause an overflow.
            jpeg_finish_decompress(&cinfo);
            jpeg_destroy_decompress(&cinfo);
            return nullptr;
        }
        memcpy(pixelWriteBuffer, buffer[0], row_stride);
        pixelWriteBuffer += row_stride;
    }

    // Step 7: Finish decompression
    jpeg_finish_decompress(&cinfo);

    // Step 8: Release JPEG decompression object
    jpeg_destroy_decompress(&cinfo);

    return std::make_unique<Bitmap>(cinfo.output_width,
                                    cinfo.output_height,
                                    Bitmap::PixelFormat::RGB,
                                    std::move(pixelBuffer));
}