using System;
using FluentAssertions;
using Xunit;
using ZB.MOM.WW.LmxProxy.Host.Configuration;

namespace ZB.MOM.WW.LmxProxy.Host.Tests.Configuration
{
    public class ConfigurationValidatorTests
    {
        private static LmxProxyConfiguration ValidConfig() => new LmxProxyConfiguration();

        [Fact]
        public void ValidConfig_PassesValidation()
        {
            var config = ValidConfig();
            Action act = () => ConfigurationValidator.ValidateAndLog(config);
            act.Should().NotThrow();
        }

        [Theory]
        [InlineData(0)]
        [InlineData(-1)]
        [InlineData(70000)]
        public void InvalidGrpcPort_Throws(int port)
        {
            var config = ValidConfig();
            config.GrpcPort = port;
            Action act = () => ConfigurationValidator.ValidateAndLog(config);
            act.Should().Throw<InvalidOperationException>().Where(e => e.Message.Contains("GrpcPort"));
        }

        [Fact]
        public void InvalidMonitorInterval_Throws()
        {
            var config = ValidConfig();
            config.Connection.MonitorIntervalSeconds = 0;
            Action act = () => ConfigurationValidator.ValidateAndLog(config);
            act.Should().Throw<InvalidOperationException>().Where(e => e.Message.Contains("MonitorIntervalSeconds"));
        }

        [Fact]
        public void InvalidChannelCapacity_Throws()
        {
            var config = ValidConfig();
            config.Subscription.ChannelCapacity = -1;
            Action act = () => ConfigurationValidator.ValidateAndLog(config);
            act.Should().Throw<InvalidOperationException>().Where(e => e.Message.Contains("ChannelCapacity"));
        }

        [Fact]
        public void InvalidChannelFullMode_Throws()
        {
            var config = ValidConfig();
            config.Subscription.ChannelFullMode = "InvalidMode";
            Action act = () => ConfigurationValidator.ValidateAndLog(config);
            act.Should().Throw<InvalidOperationException>().Where(e => e.Message.Contains("ChannelFullMode"));
        }

        [Fact]
        public void InvalidResetPeriodDays_Throws()
        {
            var config = ValidConfig();
            config.ServiceRecovery.ResetPeriodDays = 0;
            Action act = () => ConfigurationValidator.ValidateAndLog(config);
            act.Should().Throw<InvalidOperationException>().Where(e => e.Message.Contains("ResetPeriodDays"));
        }

        [Fact]
        public void NegativeFailureDelay_Throws()
        {
            var config = ValidConfig();
            config.ServiceRecovery.FirstFailureDelayMinutes = -1;
            Action act = () => ConfigurationValidator.ValidateAndLog(config);
            act.Should().Throw<InvalidOperationException>().Where(e => e.Message.Contains("FirstFailureDelayMinutes"));
        }
    }
}
