using System.Net.Sockets;
using Microsoft.Extensions.Logging.Abstractions;
using NATS.Server.Auth;
using NATS.Server.Protocol;

namespace NATS.Server.Core.Tests.Server;

public class CoreServerClientAccessorsParityBatch2Tests
{
    [Fact]
    public void Client_protocol_constants_match_go_values()
    {
        ClientProtocolVersion.ClientProtoZero.ShouldBe(0);
        ClientProtocolVersion.ClientProtoInfo.ShouldBe(1);

        ((int)ClientConnectionType.NonClient).ShouldBe(0);
        ((int)ClientConnectionType.Nats).ShouldBe(1);
        ((int)ClientConnectionType.Mqtt).ShouldBe(2);
        ((int)ClientConnectionType.WebSocket).ShouldBe(3);
    }

    [Fact]
    public void NatsClient_getters_and_client_type_behave_as_expected()
    {
        using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        using var stream = new MemoryStream();

        var opts = new NatsOptions();
        var info = new ServerInfo
        {
            ServerId = "srv1",
            ServerName = "srv",
            Version = "1.0.0",
            Host = "127.0.0.1",
            Port = 4222,
        };
        var auth = AuthService.Build(opts);
        var nonce = new byte[] { 1, 2, 3 };
        var stats = new ServerStats();

        using var client = new NatsClient(
            id: 42,
            stream: stream,
            socket: socket,
            options: opts,
            serverInfo: info,
            authService: auth,
            nonce: nonce,
            logger: NullLogger.Instance,
            serverStats: stats);

        client.ClientType().ShouldBe(ClientConnectionType.Nats);
        client.IsWebSocket = true;
        client.ClientType().ShouldBe(ClientConnectionType.WebSocket);
        client.IsWebSocket = false;
        client.IsMqtt = true;
        client.ClientType().ShouldBe(ClientConnectionType.Mqtt);
        client.GetName().ShouldBe(string.Empty);
        client.GetNonce().ShouldBe(nonce);
        client.ToString().ShouldContain("cid=42");
    }

    [Fact]
    public void NatsClient_client_type_non_client_when_kind_is_not_client()
    {
        using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        using var stream = new MemoryStream();

        var opts = new NatsOptions();
        var info = new ServerInfo
        {
            ServerId = "srv1",
            ServerName = "srv",
            Version = "1.0.0",
            Host = "127.0.0.1",
            Port = 4222,
        };
        var auth = AuthService.Build(opts);
        var stats = new ServerStats();

        using var routeClient = new NatsClient(
            id: 7,
            stream: stream,
            socket: socket,
            options: opts,
            serverInfo: info,
            authService: auth,
            nonce: null,
            logger: NullLogger.Instance,
            serverStats: stats,
            kind: ClientKind.Router);

        routeClient.ClientType().ShouldBe(ClientConnectionType.NonClient);
    }
}
