using System.Buffers;
using System.Text;
using NATS.Server.Protocol;

namespace NATS.Server.Core.Tests.ProtocolParity;

public class ProtocolParserSnippetGapParityTests
{
    [Fact]
    public void ProtoSnippet_returns_empty_quotes_when_start_is_out_of_range()
    {
        var bytes = "PING"u8.ToArray();
        var snippet = NatsParser.ProtoSnippet(bytes.Length, 2, bytes);
        snippet.ShouldBe("\"\"");
    }

    [Fact]
    public void ProtoSnippet_limits_to_requested_window_and_quotes_output()
    {
        var bytes = "ABCDEFGHIJ"u8.ToArray();
        var snippet = NatsParser.ProtoSnippet(2, 4, bytes);
        snippet.ShouldBe("\"CDEF\"");
    }

    [Fact]
    public void ProtoSnippet_matches_go_behavior_when_max_runs_past_buffer_end()
    {
        var bytes = "ABCDE"u8.ToArray();
        var snippet = NatsParser.ProtoSnippet(0, 32, bytes);
        snippet.ShouldBe("\"ABCD\"");
    }

    [Fact]
    public void Parse_exceeding_max_control_line_includes_snippet_context_in_error()
    {
        var parser = new NatsParser();
        var longSubject = new string('a', NatsProtocol.MaxControlLineSize + 1);
        var input = Encoding.ASCII.GetBytes($"PUB {longSubject} 0\r\n\r\n");
        ReadOnlySequence<byte> buffer = new(input);

        var ex = Should.Throw<ProtocolViolationException>(() => parser.TryParse(ref buffer, out _));
        ex.Message.ShouldContain("Maximum control line exceeded");
        ex.Message.ShouldContain("snip=");
    }
}
