
namespace Quadarax.Foundation.Core.Data.Diff
{
    public abstract class DiffEntry
    {
        public enum CompareStateEnum
        {
            NotInitialized,
            BothNull,
            CurrentNull,
            OtherNull,
            CurrentSmaller,
            CurrentGrater,
            Equals,
            DifferentKey
        }

        public object? Item { get; private set; }
        public CompareStateEnum CompareState { get; private set; }

        protected DiffEntry(object item)
        {
            SetItem(item);
        }
        protected DiffEntry()
        {
            CompareState = CompareStateEnum.NotInitialized;
        }


        public abstract object GetKey();

        internal void SetItem(object item)
        {
            Item = item;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <returns>-1 = both null, 0 - current null, 1 - other null, 2 - current smaller, 3 - current bigger, 4 - equals, 5 - different key</returns>
        public CompareStateEnum Compare(DiffEntry? other)
        {
            if (other == null && Item == null)
                return SetCompareState(CompareStateEnum.BothNull);
            if (Item == null)
                return SetCompareState(CompareStateEnum.CurrentNull);
            if (other == null)
                return SetCompareState(CompareStateEnum.OtherNull);

            if (!Equals(GetKey(), other.GetKey()))
                return SetCompareState(CompareStateEnum.DifferentKey);

            return OnCompareEquality(other);
        }

        public TItem? GetItem<TItem>()
        {
            return (TItem?)Item;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <returns>2 - current smaller, 3 - current bigger, 4 - equals</returns>
        protected abstract CompareStateEnum OnCompareEquality(DiffEntry other);

        internal CompareStateEnum SetCompareState(CompareStateEnum state)
        {
            CompareState = state;
            return state;
        }
    }
}
