using ZB.MOM.WW.Configuration;

namespace ZB.MOM.WW.Configuration.Tests;

public sealed class ValidationBuilderTests
{
    [Theory]
    [InlineData(0, false)]
    [InlineData(1, true)]
    [InlineData(65535, true)]
    [InlineData(65536, false)]
    public void Port_validates_range(int port, bool valid)
    {
        var b = new ValidationBuilder();
        b.Port(port, "X:Port");
        Assert.Equal(valid, b.IsValid);
    }

    [Theory]
    [InlineData(null, false)]
    [InlineData("", false)]
    [InlineData("   ", false)]
    [InlineData("ok", true)]
    public void Required_rejects_null_empty_whitespace(string? value, bool valid)
    {
        var b = new ValidationBuilder();
        b.Required(value, "X:Name");
        Assert.Equal(valid, b.IsValid);
    }

    [Theory]
    [InlineData("host:5000", true)]
    [InlineData("host", false)]
    [InlineData("host:0", false)]
    [InlineData("host:notaport", false)]
    [InlineData("::1", false)]
    public void HostPort_validates_endpoint(string value, bool valid)
    {
        var b = new ValidationBuilder();
        b.HostPort(value, "X:Endpoint");
        Assert.Equal(valid, b.IsValid);
    }

    [Fact]
    public void PositiveTimeSpan_rejects_zero_and_negative()
    {
        var b = new ValidationBuilder();
        b.PositiveTimeSpan(TimeSpan.Zero, "X:T1").PositiveTimeSpan(TimeSpan.FromSeconds(-1), "X:T2");
        Assert.Equal(2, b.Failures.Count);
    }

    [Fact]
    public void OneOf_is_case_insensitive()
    {
        var b = new ValidationBuilder();
        b.OneOf("CENTRAL", new[] { "Central", "Site" }, "X:Role");
        Assert.True(b.IsValid);
    }

    [Fact]
    public void OneOf_null_value_fails()
    {
        var b = new ValidationBuilder();
        b.OneOf(null, new[] { "Central", "Site" }, "X:Role");
        Assert.False(b.IsValid);
        Assert.Contains(b.Failures, f => f.Contains("X:Role"));
    }

    [Fact]
    public void MinCount_requires_minimum()
    {
        var b = new ValidationBuilder();
        b.MinCount(new[] { "a" }, 2, "X:Seeds");
        Assert.False(b.IsValid);
    }

    [Fact]
    public void Accumulates_all_failures_and_RequireThat_Add_work()
    {
        var b = new ValidationBuilder();
        b.Required(null, "A").RequireThat(false, "B failed").Add("C failed");
        Assert.Equal(3, b.Failures.Count);
    }
}
