//-----------------------------------------------------------------------
// 
//     Copyright (c) Microsoft Corporation.
// 
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.Runtime.InteropServices;
    /// 
    /// The native version of the JET_RSTINFO structure.
    /// 
    [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.")]
    internal struct NATIVE_RSTINFO
    {
        /// 
        /// The size of a NATIVE_RSTINFO structure.
        /// 
        public static readonly int SizeOfRstinfo = Marshal.SizeOf(typeof(NATIVE_RSTINFO));
        /// 
        /// Size of the structure.
        /// 
        public uint cbStruct;
        /// 
        /// The array of  structures.
        /// 
        public unsafe NATIVE_RSTMAP* rgrstmap;
        /// 
        /// The number of elements in the restore-map array.
        /// 
        public uint crstmap;
        /// 
        /// The log position at which it stopped.
        /// 
        public JET_LGPOS lgposStop;
        /// 
        /// The time at which it stopped.
        /// 
        public JET_LOGTIME logtimeStop;
        /// 
        /// The callback to the status function.
        /// 
        public NATIVE_PFNSTATUS pfnStatus;
    }
    /// 
    /// Contains optional input and output parameters for JetRetrieveColumn.
    /// 
    [SuppressMessage(
        "Microsoft.StyleCop.CSharp.NamingRules",
        "SA1300:ElementMustBeginWithUpperCaseLetter",
        Justification = "This should match the unmanaged API, which isn't capitalized.")]
    [Serializable]
    public class JET_RSTINFO : IContentEquatable, IDeepCloneable
    {
        /// 
        /// Gets or sets the array of  structures.
        /// 
        public JET_RSTMAP[] rgrstmap { get; set; }
        /// 
        /// Gets or sets the number of elements in the restore-map array.
        /// 
        public int crstmap { get; set; }
        /// 
        /// Gets or sets the log position to stop recovery at.
        /// 
        public JET_LGPOS lgposStop { get; set; }
        /// 
        /// Gets or sets the time at which it stopped.
        /// 
        public JET_LOGTIME logtimeStop { get; set; }
        /// 
        /// Gets or sets the callback to Gets or sets the status function.
        /// 
        public JET_PFNSTATUS pfnStatus { get; set; }
        /// 
        /// Returns a  that represents the current .
        /// 
        /// 
        /// A  that represents the current .
        /// 
        public override string ToString()
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "JET_RSTINFO(crstmap={0})",
                this.crstmap);
        }
        /// 
        /// 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 ContentEquals(JET_RSTINFO other)
        {
            if (null == other)
            {
                return false;
            }
            this.CheckMembersAreValid();
            other.CheckMembersAreValid();
            return this.crstmap == other.crstmap
                   && this.lgposStop == other.lgposStop
                   && this.logtimeStop == other.logtimeStop
                   && this.pfnStatus == other.pfnStatus
                   && Util.ArrayObjectContentEquals(this.rgrstmap, other.rgrstmap, this.crstmap);
        }
        /// 
        /// Returns a deep copy of the object.
        /// 
        /// A deep copy of the object.
        public JET_RSTINFO DeepClone()
        {
            var result = (JET_RSTINFO)this.MemberwiseClone();
            result.rgrstmap = Util.DeepCloneArray(this.rgrstmap);
            return result;
        }
        /// 
        /// Check this object to make sure its parameters are valid.
        /// 
        internal void CheckMembersAreValid()
        {
            if (this.crstmap < 0)
            {
                throw new ArgumentOutOfRangeException("crstmap", this.crstmap, "cannot be negative");                
            }
            if (null == this.rgrstmap && this.crstmap > 0)
            {
                throw new ArgumentOutOfRangeException("crstmap", this.crstmap, "must be zero");
            }
            if (null != this.rgrstmap && this.crstmap > this.rgrstmap.Length)
            {
                throw new ArgumentOutOfRangeException(
                    "crstmap",
                    this.crstmap,
                    "cannot be greater than the length of rgrstmap");
            }
        }
        /// 
        /// Get a native version of this managed structure.
        /// 
        /// A native version of this object.
        internal NATIVE_RSTINFO GetNativeRstinfo()
        {
            this.CheckMembersAreValid();
            var native = new NATIVE_RSTINFO
            {
                cbStruct = (uint)NATIVE_RSTINFO.SizeOfRstinfo,
                crstmap = checked((uint)this.crstmap),
                lgposStop = this.lgposStop,
                logtimeStop = this.logtimeStop
            };
            return native;
        }
    }
}