using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Client.Shared.Models;

namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Tests.Models;

public class ConnectionSettingsTests
{
    [Fact]
    public void Defaults_AreCorrect()
    {
        var settings = new ConnectionSettings();

        settings.EndpointUrl.ShouldBe(string.Empty);
        settings.FailoverUrls.ShouldBeNull();
        settings.Username.ShouldBeNull();
        settings.Password.ShouldBeNull();
        settings.SecurityMode.ShouldBe(SecurityMode.None);
        settings.SessionTimeoutSeconds.ShouldBe(60);
        settings.AutoAcceptCertificates.ShouldBeTrue();
        settings.CertificateStorePath.ShouldContain("OtOpcUaClient");
        settings.CertificateStorePath.ShouldContain("pki");
    }

    [Fact]
    public void Validate_ThrowsOnNullEndpointUrl()
    {
        var settings = new ConnectionSettings { EndpointUrl = null! };
        Should.Throw<ArgumentException>(() => settings.Validate())
            .ParamName.ShouldBe("EndpointUrl");
    }

    [Fact]
    public void Validate_ThrowsOnEmptyEndpointUrl()
    {
        var settings = new ConnectionSettings { EndpointUrl = "" };
        Should.Throw<ArgumentException>(() => settings.Validate())
            .ParamName.ShouldBe("EndpointUrl");
    }

    [Fact]
    public void Validate_ThrowsOnWhitespaceEndpointUrl()
    {
        var settings = new ConnectionSettings { EndpointUrl = "   " };
        Should.Throw<ArgumentException>(() => settings.Validate())
            .ParamName.ShouldBe("EndpointUrl");
    }

    [Fact]
    public void Validate_ThrowsOnZeroTimeout()
    {
        var settings = new ConnectionSettings
        {
            EndpointUrl = "opc.tcp://localhost:4840",
            SessionTimeoutSeconds = 0
        };
        Should.Throw<ArgumentException>(() => settings.Validate())
            .ParamName.ShouldBe("SessionTimeoutSeconds");
    }

    [Fact]
    public void Validate_ThrowsOnNegativeTimeout()
    {
        var settings = new ConnectionSettings
        {
            EndpointUrl = "opc.tcp://localhost:4840",
            SessionTimeoutSeconds = -1
        };
        Should.Throw<ArgumentException>(() => settings.Validate())
            .ParamName.ShouldBe("SessionTimeoutSeconds");
    }

    [Fact]
    public void Validate_ThrowsOnTimeoutAbove3600()
    {
        var settings = new ConnectionSettings
        {
            EndpointUrl = "opc.tcp://localhost:4840",
            SessionTimeoutSeconds = 3601
        };
        Should.Throw<ArgumentException>(() => settings.Validate())
            .ParamName.ShouldBe("SessionTimeoutSeconds");
    }

    [Fact]
    public void Validate_SucceedsWithValidSettings()
    {
        var settings = new ConnectionSettings
        {
            EndpointUrl = "opc.tcp://localhost:4840",
            SessionTimeoutSeconds = 120
        };
        Should.NotThrow(() => settings.Validate());
    }
}