// --------------------------------------------------------------------------------------------------------------------
// 
//     Copyright (c) Microsoft Corporation.
// 
// 
//   Information context surrounded data emitted from JET_PFNEMITLOGDATA.
// 
// --------------------------------------------------------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Windows8
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.Runtime.InteropServices;
    /// 
    /// Information context surrounded data emitted from JET_PFNEMITLOGDATA.
    /// 
    [SuppressMessage(
        "Microsoft.StyleCop.CSharp.NamingRules",
        "SA1305:FieldNamesMustNotUseHungarianNotation",
        Justification = "This should match the name of the unmanaged structure.")]
    [SuppressMessage(
        "Microsoft.StyleCop.CSharp.NamingRules",
        "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter",
        Justification = "This should match the unmanaged API, which isn't capitalized.")]
    [StructLayout(LayoutKind.Sequential)]
    [Serializable]
    internal struct NATIVE_COMMIT_ID
    {
        /// 
        /// Signature for this log sequence.
        /// 
        public NATIVE_SIGNATURE signLog;
        /// 
        /// Reserved value for proper alignment on x86.
        /// 
        public int reserved;
        /// 
        /// Commit-id for this commit transaction.
        /// 
        public long commitId;
    }
    /// 
    /// Information context surrounded data emitted from JET_PFNEMITLOGDATA.
    /// 
    [SuppressMessage(
        "Microsoft.StyleCop.CSharp.NamingRules",
        "SA1300:ElementMustBeginWithUpperCaseLetter",
        Justification = "This should match the unmanaged API, which isn't capitalized.")]
    public class JET_COMMIT_ID : IComparable, IEquatable
    {
        /// 
        /// Signature for this log sequence.
        /// 
        private readonly JET_SIGNATURE signLog;
        /// 
        /// Commit-id for this commit transaction.
        /// 
        private readonly long commitId;
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// The native version of the structure.
        /// to use as the data source.
        internal JET_COMMIT_ID(NATIVE_COMMIT_ID native)
        {
            this.signLog = new JET_SIGNATURE(native.signLog);
            this.commitId = native.commitId;
        }
#if MANAGEDESENT_ON_CORECLR
        /// 
        /// Initializes a new instance of the  class. This
        /// is for testing purposes only.
        /// 
        /// This is being implemented in new Windows UI only because the Desktop test
        /// code uses reflection to create the object, and the new Windows UI reflection does not
        /// appear to work in this scenario -- Activator.CreateInstance() reflection seems to only
        /// work with exising public constructors.
        /// The log signature for this sequence.
        /// The commit identifier for this commit transaction.
        internal JET_COMMIT_ID(JET_SIGNATURE signature, long commitId)
        {
            this.signLog = signature;
            this.commitId = commitId;
        }
#endif // MANAGEDESENT_ON_CORECLR
        /// 
        /// Determine whether one commitid is before another commitid.
        /// 
        /// The first commitid to compare.
        /// The second commitid to compare.
        /// True if lhs comes before rhs.
        public static bool operator <(JET_COMMIT_ID lhs, JET_COMMIT_ID rhs)
        {
            return lhs.CompareTo(rhs) < 0;
        }
        /// 
        /// Determine whether one commitid is before another commitid.
        /// 
        /// The first commitid to compare.
        /// The second commitid to compare.
        /// True if lhs comes after rhs.
        public static bool operator >(JET_COMMIT_ID lhs, JET_COMMIT_ID rhs)
        {
            return lhs.CompareTo(rhs) > 0;
        }
        /// 
        /// Determine whether one commitid is before another commitid.
        /// 
        /// The first commitid to compare.
        /// The second commitid to compare.
        /// True if lhs comes before or equal to rhs.
        public static bool operator <=(JET_COMMIT_ID lhs, JET_COMMIT_ID rhs)
        {
            return lhs.CompareTo(rhs) <= 0;
        }
        /// 
        /// Determine whether one commitid is before another commitid.
        /// 
        /// The first commitid to compare.
        /// The second commitid to compare.
        /// True if lhs comes after or equal to rhs.
        public static bool operator >=(JET_COMMIT_ID lhs, JET_COMMIT_ID rhs)
        {
            return lhs.CompareTo(rhs) >= 0;
        }
        /// 
        /// Determine whether one commitid is is equal to another commitid.
        /// 
        /// The first commitid to compare.
        /// The second commitid to compare.
        /// True if lhs comes is equal to rhs.
        public static bool operator ==(JET_COMMIT_ID lhs, JET_COMMIT_ID rhs)
        {
            return lhs.CompareTo(rhs) == 0;
        }
        /// 
        /// Determine whether one commitid is not equal to another commitid.
        /// 
        /// The first commitid to compare.
        /// The second commitid to compare.
        /// True if lhs comes is not equal to rhs.
        public static bool operator !=(JET_COMMIT_ID lhs, JET_COMMIT_ID rhs)
        {
            return lhs.CompareTo(rhs) != 0;
        }
        /// 
        /// Generate a string representation of the structure.
        /// 
        /// The structure as a string.
        public override string ToString()
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "JET_COMMIT_ID({0}:{1}",
                this.signLog,
                this.commitId);
        }
        /// 
        /// Returns a value comparing this instance with another.
        /// 
        /// An instance to compare with this instance.
        /// 
        /// A signed value representing the relative positions of the instances.
        /// 
        public int CompareTo(JET_COMMIT_ID other)
        {
            if ((object)other == null)
            {
                return this.commitId > 0 ? 1 : 0;
            }
            if (this.signLog != other.signLog)
                {
                throw new ArgumentException("The commit-ids belong to different log-streams");
                }
            return this.commitId.CompareTo(other.commitId);
        }
        /// 
        /// Returns a value indicating whether this instance is equal
        /// to another instance.
        /// 
        /// An object to compare with this instance.
        /// true if the two instances are equal.
        public bool Equals(JET_COMMIT_ID other)
        {
            return this.CompareTo(other) == 0;
        }
        /// 
        /// Returns a value indicating whether this instance is equal
        /// to another instance.
        /// 
        /// An object to compare with this instance.
        /// true if the two instances are equal.
        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }
            return this.CompareTo((JET_COMMIT_ID)obj) == 0;
        }
        /// 
        /// Returns the hash code for this instance.
        /// 
        /// The hash code for this instance.
        public override int GetHashCode()
        {
            return this.commitId.GetHashCode()
                   ^ this.signLog.GetHashCode();
        }
        /// 
        /// Converts the class to a NATIVE_COMMIT_ID structure.
        /// 
        /// A NATIVE_COMMIT_ID structure.
        internal NATIVE_COMMIT_ID GetNativeCommitId()
        {
            NATIVE_COMMIT_ID native = new NATIVE_COMMIT_ID();
            native.signLog = this.signLog.GetNativeSignature();
            native.commitId = checked((long)this.commitId);
            return native;
        }
    }
}