﻿using System;
using System.Runtime.Serialization;

namespace LanguageExt
{
    /// <summary>
    /// Supports the building of record types (classes with sets of readonly field values)
    /// Provides structural equality testing, ordering, and hashing
    /// </summary>
    /// <typeparam name="A">Type to provide methods for</typeparam>
    public static class RecordTypeIgnoreBase<A>
    {
        static RecordTypeIgnoreBase()
        {
            Hash = IL.GetHashCode<A>(false);
            Equality = IL.Equals<A>(false);
            EqualityTyped = IL.EqualsTyped<A>(false);
            Compare = IL.Compare<A>(false);
            ToString = IL.ToString<A>(false);
            SetObjectData = IL.SetObjectData<A>(false);
            GetObjectData = IL.GetObjectData<A>(false);
        }

        /// <summary>
        /// General hash code function for record types
        /// </summary>
        public static readonly Func<A, int> Hash;

        /// <summary>
        /// General equality function for record types
        /// </summary>
        public static readonly Func<A, object, bool> Equality;

        /// <summary>
        /// General typed equality function for record types
        /// </summary>
        public static readonly Func<A, A, bool> EqualityTyped;

        /// <summary>
        /// General typed comparison function for record types
        /// </summary>
        public static readonly Func<A, A, int> Compare;

        /// <summary>
        /// General ToString function
        /// </summary>
        public new static readonly Func<A, string> ToString;

        /// <summary>
        /// De-serialise an A
        /// </summary>
        public static readonly Action<A, SerializationInfo> SetObjectData;

        /// <summary>
        /// Serialise an A
        /// </summary>
        public static readonly Action<A, SerializationInfo> GetObjectData;

        [Obsolete("Don't use Equals - use either RecordType<A>.Equality or RecordType<A>.EqualityTyped")]
        public new static bool Equals(object objA, object objB)
        {
            throw new InvalidOperationException("Don't use Equals - use either RecordType<A>.Equality or RecordType<A>.EqualityTyped");
        }
    }
}
