using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening;
using ZB.MOM.WW.ScadaBridge.Commons.Validators;

namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Validators;

public class MxGatewayEndpointConfigValidatorTests
{
    private static MxGatewayEndpointConfig Valid() => new()
    {
        Endpoint = "http://gw:5000",
        ApiKey = "key",
    };

    [Fact]
    public void Validate_ValidConfig_IsValid()
    {
        var result = MxGatewayEndpointConfigValidator.Validate(Valid());
        Assert.True(result.IsValid);
        Assert.Empty(result.Errors);
    }

    [Fact]
    public void Validate_MissingEndpoint_Fails()
    {
        var c = Valid();
        c.Endpoint = "";
        var r = MxGatewayEndpointConfigValidator.Validate(c);
        Assert.False(r.IsValid);
        Assert.Contains(r.Errors, e =>
            e.EntityName == "Endpoint"
            && e.Category == ValidationCategory.ConnectionConfig
            && e.Message.Contains("required", StringComparison.OrdinalIgnoreCase));
    }

    [Theory]
    [InlineData("opc.tcp://x:4840")]
    [InlineData("ftp://x")]
    [InlineData("not a url")]
    public void Validate_BadEndpointScheme_Fails(string url)
    {
        var c = Valid();
        c.Endpoint = url;
        var r = MxGatewayEndpointConfigValidator.Validate(c);
        Assert.False(r.IsValid);
        Assert.Contains(r.Errors, e => e.EntityName == "Endpoint");
    }

    [Fact]
    public void Validate_MissingApiKey_Fails()
    {
        var c = Valid();
        c.ApiKey = "";
        var r = MxGatewayEndpointConfigValidator.Validate(c);
        Assert.False(r.IsValid);
        Assert.Contains(r.Errors, e => e.EntityName == "ApiKey");
    }

    [Fact]
    public void Validate_NonPositiveReadTimeout_Fails()
    {
        var c = Valid();
        c.ReadTimeoutMs = 0;
        var r = MxGatewayEndpointConfigValidator.Validate(c);
        Assert.False(r.IsValid);
        Assert.Contains(r.Errors, e => e.EntityName == "ReadTimeoutMs");
    }

    [Fact]
    public void Validate_PrefixedFieldNames_AppearInErrors()
    {
        var c = Valid();
        c.Endpoint = "";
        var r = MxGatewayEndpointConfigValidator.Validate(c, "Primary.");
        Assert.Contains(r.Errors, e => e.EntityName == "Primary.Endpoint");
    }
}
