﻿using System;
using System.Collections.Generic;

namespace Naxis.Core.Data
{
    /// <summary>
    /// 实体基类
    /// </summary>
    /// <typeparam name="TEntityIdType"></typeparam>
    public abstract class BaseEntity<TEntityIdType> : IPersistable<TEntityIdType, int>, IEquatable<BaseEntity<TEntityIdType>> where TEntityIdType : IComparable
    {
        /// <summary>
        /// 实体Id
        /// </summary>
        public virtual TEntityIdType Id { get; set; }

        /// <summary>
        /// 版本号
        /// </summary>
        public virtual int Version { get; set; }

        /// <summary>
        /// ==
        /// </summary>
        /// <param name="persistableObject1"></param>
        /// <param name="persistableObject2"></param>
        /// <returns></returns>
        public static bool operator ==(BaseEntity<TEntityIdType> persistableObject1, BaseEntity<TEntityIdType> persistableObject2)
        {
            object obj1 = persistableObject1;
            object obj2 = persistableObject2;

            if (obj1 == null && obj2 == null)
            {
                return true;
            }
            if (obj1 == null || obj2 == null || persistableObject1.Id == null || persistableObject2.Id == null)
            {
                return false;
            }

            if (persistableObject1.Id.Equals(default(TEntityIdType)) == false && persistableObject2.Id.Equals(default(TEntityIdType)) == false)
            {
                return persistableObject1.Id.CompareTo(persistableObject2.Id) == 0;
            }

            if (persistableObject1.GetType() != persistableObject2.GetType())
            {
                return false;
            }

            return obj1 == obj2;
        }

        /// <summary>
        /// ！=
        /// </summary>
        /// <param name="persistableObject1"></param>
        /// <param name="persistableObject2"></param>
        /// <returns></returns>
        public static bool operator !=(BaseEntity<TEntityIdType> persistableObject1, BaseEntity<TEntityIdType> persistableObject2)
        {
            return !(persistableObject1 == persistableObject2);
        }

        /// <summary>
        /// 重写Equals
        /// </summary>
        /// <param name="persistableObject"></param>
        /// <returns></returns>
        public override bool Equals(object persistableObject)
        {
            return persistableObject is BaseEntity<TEntityIdType> ? this == (BaseEntity<TEntityIdType>)persistableObject : false;
        }

        /// <summary>
        /// 重写GetHashCode
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return EqualityComparer<TEntityIdType>.Default.Equals(Id, default(TEntityIdType)) == false ? Id.GetHashCode() : 0;
        }

        /// <summary>
        /// 判断两个实体是否相同
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public virtual bool Equals(BaseEntity<TEntityIdType> other)
        {
            return other == null ? false : this == other;
        }

        /// <summary>
        /// 重写ToString
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Id.Equals(default(TEntityIdType)) == false ? Id.ToString() : base.ToString();
        }
    }
}
