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

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

/// <summary>
///     Regression coverage for Driver.Galaxy-002 (High): every Galaxy <c>mx_data_type</c>
///     code in the contiguous 0..6 scheme must map to the matching <see cref="DriverDataType"/>.
///     The Int64 arm (code 6) was missing, so an Int64 attribute fell through to the
///     <see cref="DriverDataType.String"/> default — a String address-space node while
///     runtime reads decoded a boxed <c>long</c>. <see cref="DataTypeMap"/> must now agree
///     with <c>MxValueDecoder</c> / <c>MxValueEncoder</c>, which both fully support Int64.
/// </summary>
public sealed class DataTypeMapTests
{
    /// <summary>Verifies that Map maps known codes to expected driver data types.</summary>
    /// <param name="mxDataType">The Galaxy mx_data_type integer code.</param>
    /// <param name="expected">The expected driver data type.</param>
    [Theory]
    [InlineData(0, DriverDataType.Boolean)]
    [InlineData(1, DriverDataType.Int32)]
    [InlineData(2, DriverDataType.Float32)]
    [InlineData(3, DriverDataType.Float64)]
    [InlineData(4, DriverDataType.String)]
    [InlineData(5, DriverDataType.DateTime)]
    [InlineData(6, DriverDataType.Int64)]
    public void Map_KnownCode_MapsToExpectedDriverDataType(int mxDataType, DriverDataType expected)
    {
        DataTypeMap.Map(mxDataType).ShouldBe(expected);
    }

    /// <summary>Verifies that Int64 code does not fall through to String default.</summary>
    [Fact]
    public void Map_Int64Code_DoesNotFallThroughToStringDefault()
    {
        // The bug: Int64 (code 6) used to hit the `_ => String` default.
        DataTypeMap.Map(6).ShouldBe(DriverDataType.Int64);
        DataTypeMap.Map(6).ShouldNotBe(DriverDataType.String);
    }

    /// <summary>Verifies that unknown code falls back to String.</summary>
    /// <param name="mxDataType">An unrecognised Galaxy mx_data_type code.</param>
    [Theory]
    [InlineData(7)]
    [InlineData(99)]
    [InlineData(-1)]
    public void Map_UnknownCode_FallsBackToString(int mxDataType)
    {
        // Forward-compatibility fallback for codes the driver doesn't recognise.
        DataTypeMap.Map(mxDataType).ShouldBe(DriverDataType.String);
    }
}
