<?php

use Doom\Image\Renderer;
use Doom\Picture\Picture;
use Intervention\Image\Encoders\PngEncoder;

/**
 * @return array<int, array{0:int,1:int,2:int}>
 */
function testPalette(): array
{
    $palette = array_fill(0, 256, [0, 0, 0]);
    $palette[1] = [255, 0, 0];
    $palette[2] = [0, 255, 0];

    return $palette;
}

test('renders a patch to PNG bytes using configured palette', function (): void {
    $picture = new Picture(
        width: 2,
        height: 2,
        left: 0,
        top: 0,
        posts: [
            0 => [
                ['y' => 0, 'topdelta' => 0, 'pixels' => [1]],
            ],
            1 => [
                ['y' => 1, 'topdelta' => 1, 'pixels' => [2]],
            ],
        ],
    );

    $png = (string) (new Renderer(testPalette()))
        ->createPicture()
        ->render($picture)
        ->encode(new PngEncoder());

    expect(substr($png, 0, 8))->toBe("\x89PNG\r\n\x1A\n");

    $image = imagecreatefromstring($png);
    expect($image)->not->toBeFalse();

    $topLeft = imagecolorsforindex($image, imagecolorat($image, 0, 0));
    expect([$topLeft['red'], $topLeft['green'], $topLeft['blue'], $topLeft['alpha']])->toBe([255, 0, 0, 0]);

    $bottomLeft = imagecolorsforindex($image, imagecolorat($image, 0, 1));
    expect($bottomLeft['alpha'])->toBe(127);

    $bottomRight = imagecolorsforindex($image, imagecolorat($image, 1, 1));
    expect([$bottomRight['red'], $bottomRight['green'], $bottomRight['blue'], $bottomRight['alpha']])->toBe([0, 255, 0, 0]);

    imagedestroy($image);
});

test('renders with default palette when custom one is not provided', function (): void {
    $picture = new Picture(
        width: 1,
        height: 1,
        left: 0,
        top: 0,
        posts: [
            0 => [
                ['y' => 0, 'topdelta' => 0, 'pixels' => [1]],
            ],
        ],
    );

    $png = (string) (new Renderer())
        ->createPicture()
        ->render($picture)
        ->encode(new PngEncoder());
    $image = imagecreatefromstring($png);
    expect($image)->not->toBeFalse();

    $pixel = imagecolorsforindex($image, imagecolorat($image, 0, 0));
    expect([$pixel['red'], $pixel['green'], $pixel['blue']])->toBe([31, 23, 11]);

    imagedestroy($image);
});
