using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Runtime;

namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests.Runtime;

/// <summary>
///     Pins the four-bucket MxAccess severity → (AlarmSeverity, OPC UA numeric) ladder.
///     Customers see no surprise re-classification when the v2 path takes over from
///     v1's sub-attribute synthesis: the bucket boundaries match v1's
///     <c>GalaxyAlarmTracker</c> per <c>docs/v1/AlarmTracking.md</c>.
/// </summary>
public sealed class MxAccessSeverityMapperTests
{
    /// <summary>Verifies that Map assigns the expected severity bucket and OPC UA severity value.</summary>
    /// <param name="rawMxAccessSeverity">The raw MxAccess severity integer to map.</param>
    /// <param name="expectedBucket">The expected AlarmSeverity bucket.</param>
    /// <param name="expectedOpcUaSeverity">The expected OPC UA numeric severity value.</param>
    [Theory]
    [InlineData(0, AlarmSeverity.Low, MxAccessSeverityMapper.OpcUaSeverityLow)]
    [InlineData(1, AlarmSeverity.Low, MxAccessSeverityMapper.OpcUaSeverityLow)]
    [InlineData(249, AlarmSeverity.Low, MxAccessSeverityMapper.OpcUaSeverityLow)]
    [InlineData(250, AlarmSeverity.Medium, MxAccessSeverityMapper.OpcUaSeverityMedium)]
    [InlineData(499, AlarmSeverity.Medium, MxAccessSeverityMapper.OpcUaSeverityMedium)]
    [InlineData(500, AlarmSeverity.High, MxAccessSeverityMapper.OpcUaSeverityHigh)]
    [InlineData(749, AlarmSeverity.High, MxAccessSeverityMapper.OpcUaSeverityHigh)]
    [InlineData(750, AlarmSeverity.Critical, MxAccessSeverityMapper.OpcUaSeverityCritical)]
    [InlineData(999, AlarmSeverity.Critical, MxAccessSeverityMapper.OpcUaSeverityCritical)]
    [InlineData(int.MaxValue, AlarmSeverity.Critical, MxAccessSeverityMapper.OpcUaSeverityCritical)]
    public void Map_assigns_expected_bucket(int rawMxAccessSeverity, AlarmSeverity expectedBucket, int expectedOpcUaSeverity)
    {
        var (bucket, opcUa) = MxAccessSeverityMapper.Map(rawMxAccessSeverity);

        bucket.ShouldBe(expectedBucket);
        opcUa.ShouldBe(expectedOpcUaSeverity);
    }

    /// <summary>Verifies that Map clamps negative severities into the low bucket.</summary>
    [Fact]
    public void Map_clamps_negative_severities_into_low_bucket()
    {
        var (bucket, opcUa) = MxAccessSeverityMapper.Map(-100);

        bucket.ShouldBe(AlarmSeverity.Low);
        opcUa.ShouldBe(MxAccessSeverityMapper.OpcUaSeverityLow);
    }
}
