// Copyright 2012-2026 The NATS Authors
// Licensed under the Apache License, Version 2.0

using System.Reflection;
using System.Text;
using Shouldly;
using ZB.MOM.NatsNet.Server;
using ZB.MOM.NatsNet.Server.Internal;

namespace ZB.MOM.NatsNet.Server.Tests;

public sealed class ClientConnectionStubFeaturesTests
{
    [Fact]
    public void ProcessConnect_ProcessPong_AndTimers_ShouldBehave()
    {
        var (server, err) = NatsServer.NewServer(new ServerOptions
        {
            PingInterval = TimeSpan.FromMilliseconds(20),
            AuthTimeout = 0.1,
        });
        err.ShouldBeNull();

        using var ms = new MemoryStream();
        var c = new ClientConnection(ClientKind.Client, server, ms)
        {
            Cid = 9,
            Trace = true,
        };

        var connectJson = Encoding.UTF8.GetBytes("{\"echo\":false,\"headers\":true,\"name\":\"unit\"}");
        c.ProcessConnect(connectJson);
        c.Opts.Name.ShouldBe("unit");
        c.Echo.ShouldBeFalse();
        c.Headers.ShouldBeTrue();

        c.RttStart = DateTime.UtcNow - TimeSpan.FromMilliseconds(50);
        c.ProcessPong();
        c.GetRttValue().ShouldBeGreaterThan(TimeSpan.Zero);

        c.SetPingTimer();
        GetTimer(c, "_pingTimer").ShouldNotBeNull();

        c.SetAuthTimer(TimeSpan.FromMilliseconds(20));
        GetTimer(c, "_atmr").ShouldNotBeNull();

        c.TraceMsg(Encoding.UTF8.GetBytes("MSG"));
        c.FlushSignal();
        c.UpdateS2AutoCompressionLevel();

        c.SetExpirationTimer(TimeSpan.Zero);
        c.IsClosed().ShouldBeTrue();
    }

    private static Timer? GetTimer(ClientConnection c, string field)
    {
        return (Timer?)typeof(ClientConnection)
            .GetField(field, BindingFlags.Instance | BindingFlags.NonPublic)!
            .GetValue(c);
    }
}
