// Go reference: server/websocket.go — wsTLSConfig and related TLS handling.

using NATS.Server.WebSocket;
using Shouldly;

namespace NATS.Server.Transport.Tests.WebSocket;

/// <summary>
/// Tests for <see cref="WebSocketTlsConfig"/> — WebSocket-specific TLS configuration
/// with separate cert/key from the main NATS listener (Gap 15.1).
/// </summary>
public class WebSocketTlsTests
{
    // ── IsConfigured ──────────────────────────────────────────────────────────

    [Fact]
    public void IsConfigured_WithCert_ReturnsTrue()
    {
        var cfg = new WebSocketTlsConfig { CertFile = "server.pem", KeyFile = "server-key.pem" };
        cfg.IsConfigured.ShouldBeTrue();
    }

    [Fact]
    public void IsConfigured_WithoutCert_ReturnsFalse()
    {
        var cfg = new WebSocketTlsConfig();
        cfg.IsConfigured.ShouldBeFalse();
    }

    // ── Validate ──────────────────────────────────────────────────────────────

    [Fact]
    public void Validate_ValidConfig_NoErrors()
    {
        var cfg = new WebSocketTlsConfig { CertFile = "server.pem", KeyFile = "server-key.pem" };
        var result = cfg.Validate();
        result.IsValid.ShouldBeTrue();
        result.Errors.ShouldBeEmpty();
    }

    [Fact]
    public void Validate_KeyWithoutCert_HasError()
    {
        var cfg = new WebSocketTlsConfig { KeyFile = "server-key.pem" };
        var result = cfg.Validate();
        result.IsValid.ShouldBeFalse();
        result.Errors.ShouldNotBeEmpty();
    }

    [Fact]
    public void Validate_CertWithoutKey_HasError()
    {
        var cfg = new WebSocketTlsConfig { CertFile = "server.pem" };
        var result = cfg.Validate();
        result.IsValid.ShouldBeFalse();
        result.Errors.ShouldNotBeEmpty();
    }

    [Fact]
    public void Validate_EmptyConfig_Valid()
    {
        // An empty configuration means "no TLS" — that is a valid state.
        var cfg = new WebSocketTlsConfig();
        var result = cfg.Validate();
        result.IsValid.ShouldBeTrue();
        result.Errors.ShouldBeEmpty();
    }

    // ── HasChangedFrom ────────────────────────────────────────────────────────

    [Fact]
    public void HasChangedFrom_SameConfig_ReturnsFalse()
    {
        var a = new WebSocketTlsConfig
        {
            CertFile = "server.pem",
            KeyFile = "server-key.pem",
            CaFile = "ca.pem",
            RequireClientCert = true,
            InsecureSkipVerify = false,
        };

        var b = new WebSocketTlsConfig
        {
            CertFile = "server.pem",
            KeyFile = "server-key.pem",
            CaFile = "ca.pem",
            RequireClientCert = true,
            InsecureSkipVerify = false,
        };

        a.HasChangedFrom(b).ShouldBeFalse();
    }

    [Fact]
    public void HasChangedFrom_DifferentCert_ReturnsTrue()
    {
        var a = new WebSocketTlsConfig { CertFile = "old.pem", KeyFile = "old-key.pem" };
        var b = new WebSocketTlsConfig { CertFile = "new.pem", KeyFile = "new-key.pem" };

        a.HasChangedFrom(b).ShouldBeTrue();
    }

    [Fact]
    public void HasChangedFrom_NullOther_ReturnsTrue()
    {
        var cfg = new WebSocketTlsConfig { CertFile = "server.pem", KeyFile = "server-key.pem" };
        cfg.HasChangedFrom(null).ShouldBeTrue();
    }

    // ── Defaults ──────────────────────────────────────────────────────────────

    [Fact]
    public void RequireClientCert_Default_False()
    {
        var cfg = new WebSocketTlsConfig();
        cfg.RequireClientCert.ShouldBeFalse();
    }
}
