/*
 * Copyright 2025 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "experimental/rust_bmp/decoder/SkBmpRustDecoder.h"

#include <memory>
#include <utility>

#include "include/codec/SkBmpDecoder.h"
#include "include/codec/SkCodec.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkData.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkStream.h"
#include "modules/skcms/skcms.h"
#include "tests/ComparePixels.h"
#include "tests/FakeStreams.h"
#include "tests/Test.h"
#include "tools/Resources.h"

// Helper to verify pixel color at a specific location.
static void assert_pixel_color(skiatest::Reporter* r,
                              const SkPixmap& pixmap,
                              int x,
                              int y,
                              SkColor expectedColor,
                              const char* description) {
    SkASSERT(r);
    SkASSERT(x >= 0);
    SkASSERT(y >= 0);
    SkASSERT(description);

    skiatest::ReporterContext ctx(r, description);
    REPORTER_ASSERT(r, x < pixmap.width(),
                    "x=%d >= width=%d", x, pixmap.width());
    REPORTER_ASSERT(r, y < pixmap.height(),
                    "y=%d >= height=%d", y, pixmap.height());
    REPORTER_ASSERT(r, kN32_SkColorType == pixmap.colorType(),
                    "kN32_SkColorType != pixmap.ColorType()=%d",
                    pixmap.colorType());

    SkColor actualColor = pixmap.getColor(x, y);
    REPORTER_ASSERT(r, actualColor == expectedColor,
                    "actualColor=0x%08X != expectedColor==0x%08X at (%d,%d)",
                    actualColor, expectedColor, x, y);
}

#define REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, actualResult) \
    REPORTER_ASSERT(r, actualResult == SkCodec::kSuccess, \
                    "actualResult=\"%s\" != kSuccess", \
                    SkCodec::ResultToString(actualResult))

// Helper wrapping a call to `SkBmpRustDecoder::Decode`.
static std::unique_ptr<SkCodec> decode_bmp(skiatest::Reporter* r, const char* path) {
    skiatest::ReporterContext ctx(r, path);
    sk_sp<SkData> data = GetResourceAsData(path);
    if (!data) {
        ERRORF(r, "Missing resource: %s", path);
        return nullptr;
    }

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec =
            SkBmpRustDecoder::Decode(SkMemoryStream::Make(std::move(data)), &result);
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    return codec;
}

// Table-based test for decoding valid BMP files.
DEF_TEST(RustBmpCodec_decode_valid_bmp, r) {
    auto test = [&r](const char* description, const char* file, SkISize expectedSize,
                     SkColorType expectedColorType,
                     SkCodec::SkScanlineOrder expectedScanlineOrder) {
        skiatest::ReporterContext ctx(r, description);
        std::unique_ptr<SkCodec> codec = decode_bmp(r, file);
        if (!codec) {
            return;
        }
        REPORTER_ASSERT(r, codec->dimensions() == expectedSize,
                        "dimensions=%dx%d != expected=%dx%d",
                        codec->dimensions().width(), codec->dimensions().height(),
                        expectedSize.width(), expectedSize.height());

        // Verify color type
        SkImageInfo info = codec->getInfo();
        REPORTER_ASSERT(r, info.colorType() == expectedColorType,
                        "colorType=%d != expected=%d",
                        info.colorType(), expectedColorType);

        auto [image, result] = codec->getImage();
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
        REPORTER_ASSERT(r, image);
        REPORTER_ASSERT(r, image->width() == expectedSize.width());
        REPORTER_ASSERT(r, image->height() == expectedSize.height());
    };

    test("basic 24-bit", "images/randPixels.bmp", {8, 8}, kN32_SkColorType,
        SkCodec::kBottomUp_SkScanlineOrder);
    test("rle compression", "images/rle.bmp", {320, 240}, kN32_SkColorType,
        SkCodec::kBottomUp_SkScanlineOrder);
    test("8 bit indexed", "images/bmp-size-32x32-8bpp.bmp", {32, 32}, kN32_SkColorType,
        SkCodec::kBottomUp_SkScanlineOrder);
    test("32 bit top-down", "images/32bpp-topdown-320x240.bmp", {320, 240}, kN32_SkColorType,
        SkCodec::kTopDown_SkScanlineOrder);
}

// Test that Decode handles nullptr for the Result parameter.
DEF_TEST(RustBmpCodec_nullptr_result, r) {
    sk_sp<SkData> data = GetResourceAsData("images/randPixels.bmp");
    REPORTER_ASSERT(r, data);

    // This should not crash even when result is nullptr
    std::unique_ptr<SkCodec> codec =
            SkBmpRustDecoder::Decode(SkMemoryStream::Make(std::move(data)), nullptr);
    REPORTER_ASSERT(r, codec);
    REPORTER_ASSERT(r, codec->dimensions() == SkISize::Make(8, 8));
}

// Test that SkBmpRustDecoder correctly rejects non-BMP data.
DEF_TEST(RustBmpCodec_reject_non_bmp, r) {
    sk_sp<SkData> data = GetResourceAsData("images/color_wheel.png");
    if (!data) {
        ERRORF(r, "Missing resource: images/color_wheel.png");
        return;
    }

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec =
            SkBmpRustDecoder::Decode(SkMemoryStream::Make(std::move(data)), &result);

    // Should fail to decode PNG data as BMP
    REPORTER_ASSERT(r, !codec, "SkBmpRustDecoder should reject PNG data");
}

// Test codec reuse functionality.
DEF_TEST(RustBmpCodec_rewind, r) {
    std::unique_ptr<SkCodec> codec = decode_bmp(r, "images/randPixels.bmp");
    if (!codec) {
        return;
    }

    // Decode first time
    auto [image1, result1] = codec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result1);
    REPORTER_ASSERT(r, image1);

    // Decode again using the same codec (tests reuse)
    auto [image2, result2] = codec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result2);
    REPORTER_ASSERT(r, image2);

    // Both images should have the same dimensions
    REPORTER_ASSERT(r,
                    image1->dimensions() == image2->dimensions(),
                    "Images after rewind should have same dimensions");

    // Verify pixel data is identical
    SkBitmap bm1, bm2;
    REPORTER_ASSERT(r, bm1.tryAllocPixels(image1->imageInfo()));
    REPORTER_ASSERT(r, bm2.tryAllocPixels(image2->imageInfo()));
    REPORTER_ASSERT(r, image1->readPixels(nullptr, bm1.pixmap(), 0, 0));
    REPORTER_ASSERT(r, image2->readPixels(nullptr, bm2.pixmap(), 0, 0));

    // Use zero tolerance for exact pixel match
    const float tols[4] = {0, 0, 0, 0};
    auto error = std::function<ComparePixmapsErrorReporter>(
            [&](int x, int y, const float diffs[4]) {
        ERRORF(r, "Pixels differ at (%d, %d) after rewind. Diffs: (%f, %f, %f, %f)",
               x, y, diffs[0], diffs[1], diffs[2], diffs[3]);
    });
    ComparePixels(bm1.pixmap(), bm2.pixmap(), tols, error);
}

// Test getPixels with a pre-allocated bitmap.
DEF_TEST(RustBmpCodec_getPixels, r) {
    std::unique_ptr<SkCodec> codec = decode_bmp(r, "images/randPixels.bmp");
    if (!codec) {
        return;
    }

    SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
    SkBitmap bitmap;
    bitmap.allocPixels(info);

    SkCodec::Result result = codec->getPixels(bitmap.pixmap());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    // Verify bitmap dimensions
    REPORTER_ASSERT(r, bitmap.width() == 8);
    REPORTER_ASSERT(r, bitmap.height() == 8);

    // Spot check pixel values to verify correct decoding
    SkPixmap pixmap = bitmap.pixmap();
    assert_pixel_color(r, pixmap, 0, 0, SkColorSetARGB(0xFF, 0xBB, 0xA5, 0x70), "pixel (0,0)");
    assert_pixel_color(r, pixmap, 1, 0, SkColorSetARGB(0xFF, 0x39, 0x5F, 0x5D), "pixel (1,0)");
    assert_pixel_color(r, pixmap, 0, 1, SkColorSetARGB(0xFF, 0xBD, 0xA6, 0x0E), "pixel (0,1)");
    assert_pixel_color(r, pixmap, 1, 1, SkColorSetARGB(0xFF, 0xC0, 0x1D, 0xB6), "pixel (1,1)");
}

// Test that IsBmp correctly identifies BMP data.
DEF_TEST(RustBmpCodec_IsBmp_positive, r) {
    sk_sp<SkData> data = GetResourceAsData("images/randPixels.bmp");
    if (!data) {
        ERRORF(r, "Missing resource: images/randPixels.bmp");
        return;
    }

    bool isBmp = SkBmpRustDecoder::IsBmp(data->data(), data->size());
    REPORTER_ASSERT(r, isBmp, "IsBmp should return true for BMP data");
}

// Test that IsBmp correctly rejects non-BMP data.
DEF_TEST(RustBmpCodec_IsBmp_negative, r) {
    sk_sp<SkData> data = GetResourceAsData("images/color_wheel.png");
    if (!data) {
        ERRORF(r, "Missing resource: images/color_wheel.png");
        return;
    }

    bool isBmp = SkBmpRustDecoder::IsBmp(data->data(), data->size());
    REPORTER_ASSERT(r, !isBmp, "IsBmp should return false for PNG data");
}

// Test IsBmp with insufficient data.
DEF_TEST(RustBmpCodec_IsBmp_insufficient_data, r) {
    // BMP signature is "BM" (2 bytes), but header is larger
    const uint8_t shortData[] = {'B'};
    bool isBmp = SkBmpRustDecoder::IsBmp(shortData, sizeof(shortData));
    REPORTER_ASSERT(r, !isBmp, "IsBmp should return false for insufficient data");
}

// Table-based test for handling invalid/corrupted BMP files.
DEF_TEST(RustBmpCodec_invalid_bmp_handling, r) {
    auto test = [&r](const char* description, const char* file) {
        skiatest::ReporterContext ctx(r, description);
        sk_sp<SkData> data = GetResourceAsData(file);
        if (!data) {
            ERRORF(r, "Missing resource: %s", file);
            return;
        }

        SkCodec::Result result;
        std::unique_ptr<SkCodec> codec =
                SkBmpRustDecoder::Decode(SkMemoryStream::Make(std::move(data)), &result);

        // If we got a codec, try to decode to ensure we don't crash
        if (codec) {
            auto [image, decodeResult] = codec->getImage();
            // Any result is acceptable as long as we don't crash
            (void)image;
            (void)decodeResult;
        }
    };

    test("zero width", "empty_images/zero-width.bmp");
    test("zero height", "empty_images/zero-height.bmp");
    test("corrupted incomplete", "invalid_images/b33251605.bmp");
    test("invalid header", "invalid_images/b33651913.bmp");
    test("extreme dimensions", "invalid_images/b34778578.bmp");
    test("os2 fuzz", "invalid_images/osfuzz6288.bmp");
}

// Test explicit rewind through multiple getPixels calls.
DEF_TEST(RustBmpCodec_explicit_rewind, r) {
    std::unique_ptr<SkCodec> codec = decode_bmp(r, "images/randPixels.bmp");
    if (!codec) {
        return;
    }

    // First decode
    SkBitmap bitmap1;
    bitmap1.allocPixels(codec->getInfo());
    SkCodec::Result result1 = codec->getPixels(bitmap1.pixmap());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result1);

    // Second decode (implicitly rewinds internally)
    SkBitmap bitmap2;
    bitmap2.allocPixels(codec->getInfo());
    SkCodec::Result result2 = codec->getPixels(bitmap2.pixmap());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result2);

    // Verify dimensions match
    REPORTER_ASSERT(r, bitmap1.dimensions() == bitmap2.dimensions(),
                    "Dimensions should match after rewind");

    // Verify pixel data matches
    REPORTER_ASSERT(r, bitmap1.computeByteSize() == bitmap2.computeByteSize(),
                    "Byte sizes should match");
    REPORTER_ASSERT(r,
                    memcmp(bitmap1.getPixels(), bitmap2.getPixels(),
                           bitmap1.computeByteSize()) == 0,
                    "Pixel data should match after rewind");
}


// Test incremental decoding
DEF_TEST(RustBmpCodec_IncrementalDecode, r) {
    const char* path = "images/randPixels.bmp";
    sk_sp<SkData> data = GetResourceAsData(path);
    REPORTER_ASSERT(r, data, "Missing test image: %s", path);
    if (!data) {
        return;
    }

    // Decode with standard BMP decoder for reference
    std::unique_ptr<SkCodec> stdCodec = SkBmpDecoder::Decode(SkMemoryStream::Make(data), nullptr);
    REPORTER_ASSERT(r, stdCodec, "Failed to create standard BMP codec for %s", path);
    if (!stdCodec) {
        return;
    }

    SkBitmap reference;
    reference.allocPixels(stdCodec->getInfo());
    SkCodec::Result result = stdCodec->getPixels(reference.pixmap());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    // Now decode using Rust BMP decoder with incremental decode
    std::unique_ptr<SkCodec> rustCodec =
            SkBmpRustDecoder::Decode(SkMemoryStream::Make(data), nullptr);
    REPORTER_ASSERT(r, rustCodec, "Failed to create Rust BMP codec for %s", path);
    if (!rustCodec) {
        return;
    }

    // Verify dimensions match before decoding
    REPORTER_ASSERT(r, rustCodec->dimensions() == stdCodec->dimensions(),
                    "Rust codec dimensions should match standard codec");

    SkBitmap incremental;
    incremental.allocPixels(rustCodec->getInfo());

    result = rustCodec->startIncrementalDecode(incremental.info(),
                                               incremental.getPixels(),
                                               incremental.rowBytes());
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    // Decode all rows incrementally
    // For BMP with all data available, this should complete in one call
    result = rustCodec->incrementalDecode();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

    // Verify that Rust incremental decode produces the same output as standard BMP decoder
    REPORTER_ASSERT(r, reference.dimensions() == incremental.dimensions(),
                    "Dimensions should match");
    REPORTER_ASSERT(r, reference.computeByteSize() == incremental.computeByteSize(),
                    "Byte sizes should match");

    // Compare pixel data
    const uint8_t* refPixels = static_cast<const uint8_t*>(reference.getPixels());
    const uint8_t* incPixels = static_cast<const uint8_t*>(incremental.getPixels());
    size_t byteSize = reference.computeByteSize();

    bool pixelsMatch = memcmp(refPixels, incPixels, byteSize) == 0;
    REPORTER_ASSERT(r, pixelsMatch,
                    "Rust incremental decode should produce identical output to standard BMP "
                    "decoder");
}

// Test incremental decode with progressively available data.
// Simulates a streaming scenario where data arrives in chunks (like over a network).
// This tests true resumability: starting with partial data, getting kIncompleteInput,
// adding more data, and resuming until complete. Tests both top-down and bottom-up
// BMP images to ensure correct row ordering in both cases.
DEF_TEST(RustBmpCodec_IncrementalDecode_PartialStreaming, r) {
    struct TestCase {
        const char* path;
        const char* description;
        int expectedIterations;
        bool isTopDown;             // Used for intermediate row verification
        int expectedFirstRowsDecoded;  // Expected rows after first 8KB chunk
    };

    // Test both top-down and bottom-up BMP files.
    // expectedFirstRowsDecoded is calculated as:
    //   (kInitialBytes + kChunkSize - headerSize) / srcRowBytes
    // where srcRowBytes is the row size in the source BMP file.
    constexpr TestCase testCases[] = {
        // Top-down 32bpp: 307254 bytes, 54-byte header, row=320*4=1280 bytes
        // After first chunk: (256 + 8192 - 54) / 1280 = 6 rows
        {"images/32bpp-topdown-320x240.bmp", "top-down 320x240 32-bit", 39, true, 6},
        // Bottom-up 24bpp with ICC: 138-byte header, row=127*3 padded to 384 bytes
        // After first chunk: (256 + 8192 - 138) / 384 = 21 rows
        {"images/rgb24prof.bmp", "bottom-up 127x64 24-bit with ICC", 4, false, 21},
    };

    for (const auto& testCase : testCases) {
        skiatest::ReporterContext ctx(r, testCase.description);

        sk_sp<SkData> data = GetResourceAsData(testCase.path);
        REPORTER_ASSERT(r, data, "Missing test image: %s", testCase.path);
        if (!data) {
            continue;
        }

        // Create a HaltingStream that starts with enough data for the BMP header.
        // Use 256 bytes to accommodate various BMP header sizes (including ICC).
        constexpr size_t kInitialBytes = 256;
        constexpr size_t kChunkSize = 8 * 1024;  // Add 8KB at a time
        const size_t fullSize = data->size();
        const size_t initialBytes = std::min(kInitialBytes, fullSize);

        // Create stream and retain raw pointer before moving to codec
        auto haltingStream = std::make_unique<HaltingStream>(data, initialBytes);
        HaltingStream* streamPtr = haltingStream.get();

        // Create codec with Rust BMP decoder
        SkCodec::Result result;
        std::unique_ptr<SkCodec> codec =
                SkBmpRustDecoder::Decode(std::move(haltingStream), &result);

        REPORTER_ASSERT(r, codec, "Failed to create codec with %zu bytes, result: %s",
                        initialBytes, SkCodec::ResultToString(result));
        if (!codec) {
            continue;
        }

        // Get the image info from the streaming codec
        const SkImageInfo streamingInfo = codec->getInfo();

        // Decode the full image for comparison using standard BMP decoder,
        // requesting the same image info for valid comparison.
        std::unique_ptr<SkCodec> stdCodec =
                SkBmpDecoder::Decode(SkMemoryStream::Make(data), nullptr);
        REPORTER_ASSERT(r, stdCodec, "Failed to create standard BMP codec");
        if (!stdCodec) {
            continue;
        }

        // Verify dimensions match
        REPORTER_ASSERT(r, codec->dimensions() == stdCodec->dimensions(),
                        "Streaming codec dimensions should match standard codec");

        SkBitmap reference;
        reference.allocPixels(streamingInfo);  // Use streaming codec's info
        SkCodec::Result refResult = stdCodec->getPixels(reference.pixmap());
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, refResult);

        SkBitmap bitmap;
        bitmap.allocPixels(streamingInfo);
        // Fill with non-zero pattern to verify decoder properly writes all pixels
        memset(bitmap.getPixels(), 0xAB, bitmap.computeByteSize());

        SkCodec::Options options;
        options.fZeroInitialized = SkCodec::kNo_ZeroInitialized;
        result = codec->startIncrementalDecode(
                bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(), &options);
        REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);

        // Resumable decode loop
        int totalRowsDecoded = 0;
        int iterations = 0;
        constexpr int kMaxIterations = 1000;
        bool sawProgressiveRows = false;   // Track if we saw partial row decoding
        bool verifiedDecodedRows = false;  // Track if we verified decoded rows

        while (iterations < kMaxIterations) {
            iterations++;
            int rowsDecoded = 0;
            result = codec->incrementalDecode(&rowsDecoded);

            if (result == SkCodec::kSuccess) {
                totalRowsDecoded = rowsDecoded;
                break;
            } else if (result == SkCodec::kIncompleteInput) {
                // Track if we got partial rows (progressive rendering)
                if (rowsDecoded > 0 && rowsDecoded < codec->getInfo().height()) {
                    sawProgressiveRows = true;

                    // Verify decoded rows match reference image (not garbage 0xAB).
                    // Only check once to avoid slowing down the test.
                    if (!verifiedDecodedRows) {
                        verifiedDecodedRows = true;

                        // Verify rowsDecoded matches our expected value based on
                        // chunk size, header size, and row bytes.
                        REPORTER_ASSERT(r, rowsDecoded == testCase.expectedFirstRowsDecoded,
                                        "Expected %d rows decoded after first chunk, got %d",
                                        testCase.expectedFirstRowsDecoded, rowsDecoded);

                        const int height = codec->getInfo().height();
                        const size_t rowBytes = bitmap.rowBytes();
                        const uint8_t* bitmapPixels =
                                static_cast<const uint8_t*>(bitmap.getPixels());
                        const uint8_t* refPixels =
                                static_cast<const uint8_t*>(reference.getPixels());

                        // For top-down images: decoded rows are at positions 0 to
                        // rowsDecoded-1.
                        // For bottom-up images: decoded rows are placed at the bottom
                        // of the buffer, positions (height - rowsDecoded) to (height - 1).
                        int startRow = testCase.isTopDown ? 0 : (height - rowsDecoded);

                        bool decodedRowsMatch = true;
                        for (int i = 0; i < rowsDecoded && decodedRowsMatch; ++i) {
                            int y = startRow + i;
                            if (memcmp(bitmapPixels + y * rowBytes,
                                       refPixels + y * rowBytes,
                                       rowBytes) != 0) {
                                decodedRowsMatch = false;
                                ERRORF(r, "Decoded row %d doesn't match reference", y);
                            }
                        }
                        REPORTER_ASSERT(r, decodedRowsMatch,
                                        "Decoded rows should match reference, not garbage");
                    }
                }
                totalRowsDecoded = rowsDecoded;

                if (streamPtr->isAllDataReceived()) {
                    ERRORF(r, "Got kIncompleteInput with all data available");
                    break;
                }
                streamPtr->addNewData(kChunkSize);
            } else {
                ERRORF(r, "Unexpected result: %s", SkCodec::ResultToString(result));
                break;
            }
        }

        REPORTER_ASSERT(r, iterations < kMaxIterations,
                        "Decode loop exceeded max iterations");

        // Verify the exact iteration count for deterministic behavior
        REPORTER_ASSERT(r, iterations == testCase.expectedIterations,
                        "Expected exactly %d iterations, got %d",
                        testCase.expectedIterations, iterations);

        REPORTER_ASSERT(r, result == SkCodec::kSuccess,
                        "Should complete successfully, got %s",
                        SkCodec::ResultToString(result));
        REPORTER_ASSERT(r, totalRowsDecoded == codec->getInfo().height(),
                        "Should decode all %d rows, decoded %d",
                        codec->getInfo().height(), totalRowsDecoded);

        // Verify progressive rendering occurred
        REPORTER_ASSERT(r, sawProgressiveRows,
                        "Should see progressive row decoding with small chunk sizes");

        // Verify we checked decoded rows during partial decode
        REPORTER_ASSERT(r, verifiedDecodedRows,
                        "Should have verified decoded rows during partial decode");

        // Verify final image matches standard decoder output
        REPORTER_ASSERT(r, bitmap.dimensions() == reference.dimensions(),
                        "Dimensions should match reference");

        // Compare row by row for detailed error reporting.
        // Both decoders output rows in logical (top-down) order.
        const size_t rowBytes = bitmap.rowBytes();
        const uint8_t* bitmapPixels = static_cast<const uint8_t*>(bitmap.getPixels());
        const uint8_t* refPixels = static_cast<const uint8_t*>(reference.getPixels());
        const int height = codec->getInfo().height();

        bool allRowsMatch = true;
        for (int y = 0; y < height; ++y) {
            if (memcmp(bitmapPixels + y * rowBytes,
                       refPixels + y * rowBytes, rowBytes) != 0) {
                allRowsMatch = false;
                ERRORF(r, "Row %d doesn't match between Rust streaming and "
                          "standard decoder", y);
            }
        }
        REPORTER_ASSERT(r, allRowsMatch,
                        "Streaming decode should match standard BMP decoder output");
    }
}

// Test incomplete metadata - stream with partial BMP header
DEF_TEST(RustBmpCodec_IncompleteMetadata_PartialHeader, r) {
    // Load a valid BMP
    sk_sp<SkData> data = GetResourceAsData("images/randPixels.bmp");
    if (!data) {
        ERRORF(r, "Failed to load test image");
        return;
    }

    // Create stream with only partial header (30 bytes of 54-byte header)
    constexpr size_t kPartialSize = 30;
    sk_sp<SkData> partialData = SkData::MakeSubset(data.get(), 0, kPartialSize);
    std::unique_ptr<SkStream> partialStream = SkMemoryStream::Make(partialData);

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec =
        SkBmpRustDecoder::Decode(std::move(partialStream), &result);

    // Should fail with incomplete input (not enough for metadata)
    REPORTER_ASSERT(r, codec == nullptr,
                   "Should not create codec with incomplete metadata");
    REPORTER_ASSERT(r, result == SkCodec::kIncompleteInput,
                   "Should return kIncompleteInput, got %d", result);
}

// Test incomplete row data - stream with partial pixel data
DEF_TEST(RustBmpCodec_IncompleteRowData, r) {
    // Load a valid BMP
    sk_sp<SkData> data = GetResourceAsData("images/randPixels.bmp");
    if (!data) {
        ERRORF(r, "Failed to load test image");
        return;
    }

    // Get codec to determine dimensions
    std::unique_ptr<SkCodec> fullCodec =
        SkBmpRustDecoder::Decode(SkMemoryStream::Make(data), nullptr);
    if (!fullCodec) {
        ERRORF(r, "Failed to create codec from full data");
        return;
    }

    SkImageInfo info = fullCodec->getInfo();

    // BMP header is 54 bytes, calculate size for header + half of first row
    constexpr size_t kHeaderSize = 54;
    size_t rowBytes = info.width() * 3; // Assuming 24-bit RGB
    rowBytes = ((rowBytes + 3) / 4) * 4; // Row padding to 4-byte boundary
    size_t partialSize = kHeaderSize + (rowBytes / 2);

    // Ensure we don't exceed data size
    if (partialSize >= data->size()) {
        ERRORF(r, "Image too small for this test");
        return;
    }

    sk_sp<SkData> partialData = SkData::MakeSubset(data.get(), 0, partialSize);
    std::unique_ptr<SkStream> partialStream = SkMemoryStream::Make(partialData);

    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec =
        SkBmpRustDecoder::Decode(std::move(partialStream), &result);

    // With header data available, codec creation should succeed
    REPORTER_ASSERT(r, codec, "Codec should be created with header data available");
    REPORTER_ASSERT(r, result == SkCodec::kSuccess,
                    "Expected kSuccess for codec creation, got %s",
                    SkCodec::ResultToString(result));
    if (!codec) {
        return;
    }

    // Try to decode - should fail with kIncompleteInput since we don't have all pixel data
    SkBitmap bitmap;
    bitmap.allocPixels(info);
    SkCodec::Result decodeResult = codec->getPixels(info, bitmap.getPixels(),
                                                    bitmap.rowBytes());

    REPORTER_ASSERT(r, decodeResult == SkCodec::kIncompleteInput,
                    "Expected kIncompleteInput with partial pixel data, got %s",
                    SkCodec::ResultToString(decodeResult));
}

// Test that embedded ICC profiles in BMP V5 headers are correctly extracted and applied.
// This uses rgb24prof.bmp from the image-rs test suite, which contains an embedded ICC profile.
DEF_TEST(RustBmpCodec_ICCProfile, r) {
    const char* path = "images/rgb24prof.bmp";
    sk_sp<SkData> data = GetResourceAsData(path);
    REPORTER_ASSERT(r, data, "Missing test image: %s", path);
    if (!data) {
        return;
    }

    std::unique_ptr<SkCodec> codec =
            SkBmpRustDecoder::Decode(SkMemoryStream::Make(data), nullptr);
    REPORTER_ASSERT(r, codec, "Failed to create Rust BMP codec");
    if (!codec) {
        return;
    }

    // Verify that the codec extracted an ICC profile
    const skcms_ICCProfile* profile = codec->getICCProfile();
    REPORTER_ASSERT(r, profile,
                    "BMP with embedded ICC profile should have getICCProfile() != null");
    if (!profile) {
        return;
    }

    // Verify the profile can be used to create a color space
    sk_sp<SkColorSpace> colorSpace = SkColorSpace::Make(*profile);
    REPORTER_ASSERT(r, colorSpace, "ICC profile should be valid and create a color space");
    if (!colorSpace) {
        return;
    }

    // Verify the color space from getInfo() matches
    SkImageInfo info = codec->getInfo();
    REPORTER_ASSERT(r, info.colorSpace(), "getInfo() should have a color space");
    if (info.colorSpace()) {
        REPORTER_ASSERT(r, SkColorSpace::Equals(info.colorSpace(), colorSpace.get()),
                        "Color space from getInfo() should match ICC profile");
    }

    // Verify decoding works with the ICC profile
    auto [image, result] = codec->getImage();
    REPORTER_ASSERT_SUCCESSFUL_CODEC_RESULT(r, result);
    REPORTER_ASSERT(r, image, "Should be able to decode BMP with ICC profile");
}
