// 
//     Copyright (c) Microsoft Corporation.
// 
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Windows10
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.Runtime.InteropServices;
    /// 
    /// A structure that can be used with  to set a client context on a session.
    /// 
    [StructLayout(LayoutKind.Sequential)]
    [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules",
        "SA1305:FieldNamesMustNotUseHungarianNotation",
        Justification = "This should match the unmanaged API, which isn't capitalized.")]
    [SuppressMessage(
        "Microsoft.StyleCop.CSharp.NamingRules",
        "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter",
        Justification = "This should match the unmanaged API, which isn't capitalized.")]
    [SuppressMessage("Microsoft.StyleCop.CSharp.OrderingRules",
        "SA1202:ElementsMustBeOrderedByAccess",
        Justification = "Ordering matches the rest of the codebase.")]
    internal struct NATIVE_OPERATIONCONTEXT
    {
        /// 
        /// User ID this operation context belongs to.
        /// 
        public int ulUserID;
        /// 
        /// An operation ID identifying this operation.
        /// 
        public byte nOperationID;
        /// 
        /// Type of this operation.
        /// 
        public byte nOperationType;
        /// 
        /// The client type that this operation context belongs to.
        /// 
        public byte nClientType;
        /// 
        /// Flags for additional context that an application might want to store.
        /// 
        public byte fFlags;
    }
    /// 
    /// A type that can be used with  to set a client context on a session.
    /// 
    public struct JET_OPERATIONCONTEXT : IEquatable
    {
        #region Constructors
        /// 
        /// Initializes a new instance of the 
        /// struct.
        /// 
        /// The native 
        /// object to be based upon.
        internal JET_OPERATIONCONTEXT(ref NATIVE_OPERATIONCONTEXT native)
            : this()
        {
            this.UserID = native.ulUserID;
            this.OperationID = native.nOperationID;
            this.OperationType = native.nOperationType;
            this.ClientType = native.nClientType;
            this.Flags = native.fFlags;
        }
        #endregion
        /// 
        /// Gets or sets the user ID this operation context belongs to.
        /// 
        public int UserID { get; set; }
        /// 
        /// Gets or sets an operation ID identifying this operation.
        /// 
        public byte OperationID { get; set; }
        /// 
        /// Gets or sets the type of this operation.
        /// 
        public byte OperationType { get; set; }
        /// 
        /// Gets or sets the client type that this operation context belongs to.
        /// 
        public byte ClientType { get; set; }
        /// 
        /// Gets or sets the flags for additional context that an application might want to store.
        /// 
        public byte Flags { get; set; }
        #region operators
        /// 
        /// Determines whether two specified instances of 
        /// are equal.
        /// 
        /// The first instance to compare.
        /// The second instance to compare.
        /// True if the two instances are equal.
        public static bool operator ==(JET_OPERATIONCONTEXT lhs, JET_OPERATIONCONTEXT rhs)
        {
            return lhs.Equals(rhs);
        }
        /// 
        /// Determines whether two specified instances of 
        /// are not equal.
        /// 
        /// The first instance to compare.
        /// The second instance to compare.
        /// True if the two instances are not equal.
        public static bool operator !=(JET_OPERATIONCONTEXT lhs, JET_OPERATIONCONTEXT rhs)
        {
            return !(lhs == rhs);
        }
        #endregion
        #region IEquatable and related required functions.
        /// 
        /// 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.Equals((JET_OPERATIONCONTEXT)obj);
        }
        /// 
        /// Returns the hash code for this instance.
        /// 
        /// The hash code for this instance.
        public override int GetHashCode()
        {
            return this.UserID.GetHashCode()
                   ^ this.OperationID.GetHashCode()
                   ^ this.OperationType.GetHashCode()
                   ^ this.ClientType.GetHashCode()
                   ^ this.Flags.GetHashCode();
        }
        /// 
        /// Returns a value indicating whether this instance is equal
        /// to another instance.
        /// 
        /// An instance to compare with this instance.
        /// True if the two instances are equal.
        public bool Equals(JET_OPERATIONCONTEXT other)
        {
            bool contentEquals = 
                this.UserID == other.UserID &&
                this.OperationID == other.OperationID &&
                this.OperationType == other.OperationType &&
                this.ClientType == other.ClientType &&
                this.Flags == other.Flags;
            return contentEquals;
        }
        #endregion
        /// 
        /// Generate a string representation of the instance.
        /// 
        /// The structure as a string.
        public override string ToString()
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "JET_OPERATIONCONTEXT({0}:{1}:{2}:{3}:0x{4:x2})",
                this.UserID,
                this.OperationID,
                this.OperationType,
                this.ClientType,
                this.Flags);
        }
        /// 
        /// Gets the native (interop) version of this object.
        /// 
        /// 
        /// The native (interop) version of this object.
        /// 
        internal NATIVE_OPERATIONCONTEXT GetNativeOperationContext()
        {
            var native = new NATIVE_OPERATIONCONTEXT();
            native.ulUserID = this.UserID;
            native.nOperationID = this.OperationID;
            native.nOperationType = this.OperationType;
            native.nClientType = this.ClientType;
            native.fFlags = this.Flags;
            return native;
        }
    }
}