using FluentAssertions;
using Xunit;
using ZB.MOM.WW.LmxProxy.Host.Domain;

namespace ZB.MOM.WW.LmxProxy.Host.Tests.MxAccess
{
    public class TypedValueEqualsTests
    {
        [Fact]
        public void NullEqualsNull() => TypedValueComparer.Equals(null, null).Should().BeTrue();

        [Fact]
        public void NullNotEqualsValue() => TypedValueComparer.Equals(null, 42).Should().BeFalse();

        [Fact]
        public void ValueNotEqualsNull() => TypedValueComparer.Equals(42, null).Should().BeFalse();

        [Fact]
        public void SameTypeAndValue() => TypedValueComparer.Equals(42.5, 42.5).Should().BeTrue();

        [Fact]
        public void SameTypeDifferentValue() => TypedValueComparer.Equals(42.5, 43.0).Should().BeFalse();

        [Fact]
        public void DifferentTypes_NeverEqual() => TypedValueComparer.Equals(1, 1.0).Should().BeFalse();

        [Fact]
        public void BoolTrue() => TypedValueComparer.Equals(true, true).Should().BeTrue();

        [Fact]
        public void BoolFalse() => TypedValueComparer.Equals(false, true).Should().BeFalse();

        [Fact]
        public void String_CaseSensitive()
        {
            TypedValueComparer.Equals("DONE", "DONE").Should().BeTrue();
            TypedValueComparer.Equals("done", "DONE").Should().BeFalse();
        }

        [Fact]
        public void Array_SameElements()
        {
            TypedValueComparer.Equals(new[] { 1, 2, 3 }, new[] { 1, 2, 3 }).Should().BeTrue();
        }

        [Fact]
        public void Array_DifferentElements()
        {
            TypedValueComparer.Equals(new[] { 1, 2, 3 }, new[] { 1, 2, 4 }).Should().BeFalse();
        }

        [Fact]
        public void Array_DifferentLengths()
        {
            TypedValueComparer.Equals(new[] { 1, 2 }, new[] { 1, 2, 3 }).Should().BeFalse();
        }

        [Fact]
        public void Int32_NotEqual_ToDouble()
        {
            TypedValueComparer.Equals(1, 1.0).Should().BeFalse();
        }

        [Fact]
        public void Long_Equality()
        {
            TypedValueComparer.Equals(long.MaxValue, long.MaxValue).Should().BeTrue();
        }

        [Fact]
        public void DateTime_TickPrecision()
        {
            var dt1 = new System.DateTime(638789000000000000, System.DateTimeKind.Utc);
            var dt2 = new System.DateTime(638789000000000000, System.DateTimeKind.Utc);
            TypedValueComparer.Equals(dt1, dt2).Should().BeTrue();
        }
    }
}
