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

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

public class AggregateTypeMapperTests
{
    /// <summary>Verifies that ToNodeId returns a non-null NodeId for all AggregateType values.</summary>
    /// <param name="aggregate">The aggregate type to test.</param>
    [Theory]
    [InlineData(AggregateType.Average)]
    [InlineData(AggregateType.Minimum)]
    [InlineData(AggregateType.Maximum)]
    [InlineData(AggregateType.Count)]
    [InlineData(AggregateType.Start)]
    [InlineData(AggregateType.End)]
    [InlineData(AggregateType.StandardDeviation)]
    public void ToNodeId_ReturnsNonNullForAllValues(AggregateType aggregate)
    {
        var nodeId = AggregateTypeMapper.ToNodeId(aggregate);
        nodeId.ShouldNotBeNull();
        nodeId.IsNullNodeId.ShouldBeFalse();
    }

    /// <summary>Verifies that Average aggregate type maps to the correct OPC UA node ID.</summary>
    [Fact]
    public void ToNodeId_Average_MapsCorrectly()
    {
        AggregateTypeMapper.ToNodeId(AggregateType.Average).ShouldBe(ObjectIds.AggregateFunction_Average);
    }

    /// <summary>Verifies that Minimum aggregate type maps to the correct OPC UA node ID.</summary>
    [Fact]
    public void ToNodeId_Minimum_MapsCorrectly()
    {
        AggregateTypeMapper.ToNodeId(AggregateType.Minimum).ShouldBe(ObjectIds.AggregateFunction_Minimum);
    }

    /// <summary>Verifies that Maximum aggregate type maps to the correct OPC UA node ID.</summary>
    [Fact]
    public void ToNodeId_Maximum_MapsCorrectly()
    {
        AggregateTypeMapper.ToNodeId(AggregateType.Maximum).ShouldBe(ObjectIds.AggregateFunction_Maximum);
    }

    /// <summary>Verifies that Count aggregate type maps to the correct OPC UA node ID.</summary>
    [Fact]
    public void ToNodeId_Count_MapsCorrectly()
    {
        AggregateTypeMapper.ToNodeId(AggregateType.Count).ShouldBe(ObjectIds.AggregateFunction_Count);
    }

    /// <summary>Verifies that Start aggregate type maps to the correct OPC UA node ID.</summary>
    [Fact]
    public void ToNodeId_Start_MapsCorrectly()
    {
        AggregateTypeMapper.ToNodeId(AggregateType.Start).ShouldBe(ObjectIds.AggregateFunction_Start);
    }

    /// <summary>Verifies that End aggregate type maps to the correct OPC UA node ID.</summary>
    [Fact]
    public void ToNodeId_End_MapsCorrectly()
    {
        AggregateTypeMapper.ToNodeId(AggregateType.End).ShouldBe(ObjectIds.AggregateFunction_End);
    }

    /// <summary>Verifies that StandardDeviation aggregate type maps to the correct OPC UA node ID.</summary>
    [Fact]
    public void ToNodeId_StandardDeviation_MapsCorrectly()
    {
        AggregateTypeMapper.ToNodeId(AggregateType.StandardDeviation)
            .ShouldBe(ObjectIds.AggregateFunction_StandardDeviationPopulation);
    }

    /// <summary>Verifies that invalid aggregate type value throws ArgumentOutOfRangeException.</summary>
    [Fact]
    public void ToNodeId_InvalidValue_Throws()
    {
        Should.Throw<ArgumentOutOfRangeException>(() =>
            AggregateTypeMapper.ToNodeId((AggregateType)99));
    }
}