using NATS.Server.WebSocket;
using Shouldly;

namespace NATS.Server.Tests.WebSocket;

public class WsCompressionTests
{
    [Fact]
    public void CompressDecompress_RoundTrip()
    {
        var original = "Hello, WebSocket compression test! This is long enough to compress."u8.ToArray();
        var compressed = WsCompression.Compress(original);
        compressed.ShouldNotBeNull();
        compressed.Length.ShouldBeGreaterThan(0);

        var decompressed = WsCompression.Decompress([compressed], maxPayload: 4096);
        decompressed.ShouldBe(original);
    }

    [Fact]
    public void Decompress_ExceedsMaxPayload_Throws()
    {
        var original = new byte[1000];
        Random.Shared.NextBytes(original);
        var compressed = WsCompression.Compress(original);

        Should.Throw<InvalidOperationException>(() =>
            WsCompression.Decompress([compressed], maxPayload: 100));
    }

    [Fact]
    public void Compress_RemovesTrailing4Bytes()
    {
        var data = new byte[200];
        Random.Shared.NextBytes(data);
        var compressed = WsCompression.Compress(data);

        // The compressed data should be valid for decompression when we add the trailer back
        var decompressed = WsCompression.Decompress([compressed], maxPayload: 4096);
        decompressed.ShouldBe(data);
    }

    [Fact]
    public void Decompress_MultipleBuffers()
    {
        var original = new byte[500];
        Random.Shared.NextBytes(original);
        var compressed = WsCompression.Compress(original);

        // Split compressed data into multiple chunks
        int mid = compressed.Length / 2;
        var chunk1 = compressed[..mid];
        var chunk2 = compressed[mid..];

        var decompressed = WsCompression.Decompress([chunk1, chunk2], maxPayload: 4096);
        decompressed.ShouldBe(original);
    }
}
