using XGame.Framework.Assertions;
using System.Collections.Generic;
using System.Diagnostics;

namespace XGame.Framework
{
    public static partial class Assert
    {
        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreEqual<T>(T expected, T actual)
        {
            AreEqual(expected, actual, null);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreEqual<T>(T expected, T actual, string format, params object[] args)
        {
            AreEqual(expected, actual, EqualityComparer<T>.Default, format, args);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreEqual<TValue, TExpection>(TValue expected, TValue actual, TExpection e) where TExpection : System.Exception
        {
            AreEqual(expected, actual, EqualityComparer<TValue>.Default, e);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreEqual<T>(T expected, T actual, IEqualityComparer<T> comparer, string format, params object[] args)
        {
            if (typeof(UnityEngine.Object).IsAssignableFrom(typeof(T)))
            {
                AreEqual(expected as UnityEngine.Object, actual as UnityEngine.Object, format, args);
                return;
            }
            if (!comparer.Equals(actual, expected))
                Fail(AssertionMessageUtil.GetEqualityMessage(actual, expected, true), format, args);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreEqual<TValue, TExpection>(TValue expected, TValue actual, IEqualityComparer<TValue> comparer, TExpection e) where TExpection : System.Exception
        {
            if (typeof(UnityEngine.Object).IsAssignableFrom(typeof(TValue)))
            {
                AreEqual(expected as UnityEngine.Object, actual as UnityEngine.Object, e);
                return;
            }
            if (!comparer.Equals(actual, expected))
                Fail(AssertionMessageUtil.GetEqualityMessage(actual, expected, true), e);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreEqual(UnityEngine.Object expected, UnityEngine.Object actual, string format, params object[] args)
        {
            if (actual != expected)
                Fail(AssertionMessageUtil.GetEqualityMessage(actual, expected, true), format, args);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreEqual<TExpection>(UnityEngine.Object expected, UnityEngine.Object actual, TExpection e) where TExpection : System.Exception
        {
            if (actual != expected)
                Fail(AssertionMessageUtil.GetEqualityMessage(actual, expected, true), e);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreNotEqual<T>(T expected, T actual)
        {
            AreNotEqual(expected, actual, null);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreNotEqual<T>(T expected, T actual, string format, params object[] args)
        {
            AreNotEqual(expected, actual, EqualityComparer<T>.Default, format, args);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreNotEqual<TValue, TExpection>(TValue expected, TValue actual, TExpection e) where TExpection : System.Exception
        {
            AreNotEqual(expected, actual, EqualityComparer<TValue>.Default, e);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreNotEqual<T>(T expected, T actual, IEqualityComparer<T> comparer, string format, params object[] args)
        {
            if (typeof(UnityEngine.Object).IsAssignableFrom(typeof(T)))
            {
                AreNotEqual(expected as UnityEngine.Object, actual as UnityEngine.Object, format, args);
                return;
            }
            if (comparer.Equals(actual, expected))
                Fail(AssertionMessageUtil.GetEqualityMessage(actual, expected, false), format, args);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreNotEqual<TValue, TExpection>(TValue expected, TValue actual, IEqualityComparer<TValue> comparer, TExpection e) where TExpection : System.Exception
        {
            if (typeof(UnityEngine.Object).IsAssignableFrom(typeof(TValue)))
            {
                AreNotEqual(expected as UnityEngine.Object, actual as UnityEngine.Object, e);
                return;
            }
            if (comparer.Equals(actual, expected))
                Fail(AssertionMessageUtil.GetEqualityMessage(actual, expected, false), e);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreNotEqual(UnityEngine.Object expected, UnityEngine.Object actual, string format, params object[] args)
        {
            if (actual == expected)
                Fail(AssertionMessageUtil.GetEqualityMessage(actual, expected, false), format, args);
        }

        [Conditional(MacroDefine.XGAME_ASSERT), Conditional(MacroDefine.UNITY_EDITOR)]
        public static void AreNotEqual<TExpection>(UnityEngine.Object expected, UnityEngine.Object actual, TExpection e) where TExpection : System.Exception
        {
            if (actual == expected)
                Fail(AssertionMessageUtil.GetEqualityMessage(actual, expected, false), e);
        }

    }
}
