using TeamsISO.Engine.Domain;
using TeamsISO.Engine.Pipeline;

namespace TeamsISO.Engine.Tests.Pipeline;

public class ManagedNearestNeighborFrameScalerTests
{
    private static RawFrame Solid(int w, int h, byte b, byte g, byte r, byte a, long ts = 0)
    {
        var pixels = new byte[w * h * 4];
        for (var i = 0; i < pixels.Length; i += 4)
        {
            pixels[i + 0] = b; pixels[i + 1] = g; pixels[i + 2] = r; pixels[i + 3] = a;
        }
        return new RawFrame(w, h, ts, pixels, PixelFormat.Bgra);
    }

    [Fact]
    public void Stretch_ScalesToTargetDimensions()
    {
        var scaler = new ManagedNearestNeighborFrameScaler();
        var src = Solid(640, 360, 0x10, 0x20, 0x30, 0xFF);

        var dst = scaler.Scale(src, 1920, 1080, AspectMode.Stretch, 1234);

        dst.Width.Should().Be(1920);
        dst.Height.Should().Be(1080);
        dst.Format.Should().Be(PixelFormat.Bgra);
        dst.Pixels.Length.Should().Be(1920 * 1080 * 4);
        dst.TimestampTicks.Should().Be(1234);
        // Solid color should be preserved across the entire output
        dst.Pixels.Span[0].Should().Be(0x10);
        dst.Pixels.Span[dst.Pixels.Length - 4].Should().Be(0x10);
    }

    [Fact]
    public void Pillarbox_NarrowSource_GetsBlackBars_LeftAndRight()
    {
        var scaler = new ManagedNearestNeighborFrameScaler();
        // 1:1 aspect source going into a 16:9 target should pillarbox.
        var src = Solid(100, 100, 0x10, 0x20, 0x30, 0xFF);

        var dst = scaler.Scale(src, 1920, 1080, AspectMode.Pillarbox, 0);

        // Top-left pixel (in the bar region) should be black.
        dst.Pixels.Span[0].Should().Be(0x00);
        dst.Pixels.Span[1].Should().Be(0x00);
        dst.Pixels.Span[2].Should().Be(0x00);

        // Center pixel should carry the source color.
        var centerOffset = (1080 / 2 * 1920 + 1920 / 2) * 4;
        dst.Pixels.Span[centerOffset].Should().Be(0x10);
        dst.Pixels.Span[centerOffset + 2].Should().Be(0x30);
    }

    [Fact]
    public void Letterbox_WideSource_GetsBlackBars_TopAndBottom()
    {
        var scaler = new ManagedNearestNeighborFrameScaler();
        // 21:9 source (e.g. 2100x900) into a 16:9 target should letterbox.
        var src = Solid(2100, 900, 0x10, 0x20, 0x30, 0xFF);

        var dst = scaler.Scale(src, 1920, 1080, AspectMode.Letterbox, 0);

        // Top-left pixel should be in the bar region (black).
        dst.Pixels.Span[0].Should().Be(0x00);

        // Center pixel should carry the source color.
        var centerOffset = (1080 / 2 * 1920 + 1920 / 2) * 4;
        dst.Pixels.Span[centerOffset].Should().Be(0x10);
    }
}
