//-----------------------------------------------------------------------
// 
//     Copyright (c) Microsoft Corporation.
// 
//-----------------------------------------------------------------------
#if !MANAGEDESENT_ON_WSA // Not exposed in MSDK
namespace Microsoft.Isam.Esent.Interop
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.Runtime.InteropServices;
    /// 
    /// The native version of the JET_INSTANCE_INFO 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 unsafe struct NATIVE_INSTANCE_INFO
    {
        /// 
        /// The JET_INSTANCE of the given instance.
        /// 
        public IntPtr hInstanceId;
        /// 
        /// The name of the database instance. This value can be NULL if the
        /// instance does not have a name.
        /// 
        public IntPtr szInstanceName;
        /// 
        /// The number of databases that are attached to the database instance.
        /// cDatabases also holds the size of the arrays of strings that are
        /// returned in szDatabaseFileName, szDatabaseDisplayName, and
        /// szDatabaseSLVFileName.
        /// 
        public IntPtr cDatabases;
        /// 
        /// An array of strings, each holding the file name of a database that
        /// is attached to the database instance. The array has cDatabases
        /// elements.
        /// 
        public IntPtr* szDatabaseFileName;
        /// 
        /// An array of strings, each holding the display name of a database.
        /// This string is always null. The array has cDatabases elements.
        /// 
        public IntPtr* szDatabaseDisplayName;
        /// 
        /// An array of strings, each holding the file name of the SLV file that
        /// is attached to the database instance. The array has cDatabases
        /// elements. SLV files are not supported, so this field should be ignored.
        /// 
        [Obsolete("SLV files are not supported")]
        public IntPtr* szDatabaseSLVFileName;
    }
    /// 
    /// Receives information about running database instances when used with the
    /// JetGetInstanceInfo and JetOSSnapshotFreeze functions.
    /// 
    [SuppressMessage(
        "Microsoft.StyleCop.CSharp.NamingRules",
        "SA1300:ElementMustBeginWithUpperCaseLetter",
        Justification = "This should match the unmanaged API, which isn't capitalized.")]
    public class JET_INSTANCE_INFO : IEquatable
    {
        /// 
        /// Collection of database file names.
        /// 
        private ReadOnlyCollection databases;
        /// 
        /// Initializes a new instance of the  class.
        /// 
        internal JET_INSTANCE_INFO()
        {            
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// 
        /// The instance.
        /// 
        /// 
        /// The name of the instance.
        /// 
        /// 
        /// The databases in the instance.
        /// 
        internal JET_INSTANCE_INFO(JET_INSTANCE instance, string instanceName, string[] databases)
        {
            this.hInstanceId = instance;
            this.szInstanceName = instanceName;
            if (null == databases)
            {
                this.cDatabases = 0;
                this.databases = null;
            }
            else
            {
                this.cDatabases = databases.Length;
                this.databases = new ReadOnlyCollection(databases);
            }
        }
        /// 
        /// Gets the JET_INSTANCE of the given instance.
        /// 
        public JET_INSTANCE hInstanceId { get; private set; }
        /// 
        /// Gets the name of the database instance. This value can be null if
        /// the instance does not have a name.
        /// 
        public string szInstanceName { get; private set; }
        /// 
        /// Gets the number of databases that are attached to the database instance.
        /// 
        public int cDatabases { get; private set; }
        /// 
        /// Gets a collection of strings, each holding the file name of a database
        /// that is attached to the database instance. The array has cDatabases
        /// elements.
        /// 
        public IList szDatabaseFileName
        {
            get
            {
                return this.databases;
            }
        }
        /// 
        /// 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 || this.GetType() != obj.GetType())
            {
                return false;
            }
            return this.Equals((JET_INSTANCE_INFO)obj);
        }
        /// 
        /// Generate a string representation of the instance.
        /// 
        /// The structure as a string.
        public override string ToString()
        {
            return string.Format(CultureInfo.InvariantCulture, "JET_INSTANCE_INFO({0})", this.szInstanceName);
        }
        /// 
        /// Returns the hash code for this instance.
        /// 
        /// The hash code for this instance.
        public override int GetHashCode()
        {
            int hash = this.hInstanceId.GetHashCode()
                   ^ (this.szInstanceName ?? string.Empty).GetHashCode()
                   ^ this.cDatabases << 20;
            for (int i = 0; i < this.cDatabases; ++i)
            {
                hash ^= this.szDatabaseFileName[i].GetHashCode();
            }
            return hash;
        }
        /// 
        /// 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_INSTANCE_INFO other)
        {
            if (null == other)
            {
                return false;
            }
            if (this.hInstanceId != other.hInstanceId
                || this.szInstanceName != other.szInstanceName
                || this.cDatabases != other.cDatabases)
            {
                return false;
            }
            for (int i = 0; i < this.cDatabases; ++i)
            {
                if (this.szDatabaseFileName[i] != other.szDatabaseFileName[i])
                {
                    return false;
                }
            }
            return true;
        }
        /// 
        /// Set the properties of the object from a native instance info where the
        /// strings in the NATIVE_INSTANCE_INFO are ASCII.
        /// 
        /// The native instance info.
        internal void SetFromNativeAscii(NATIVE_INSTANCE_INFO native)
        {
            this.hInstanceId = new JET_INSTANCE { Value = native.hInstanceId };
            this.szInstanceName = Marshal.PtrToStringAnsi(native.szInstanceName);
            this.cDatabases = checked((int)native.cDatabases);
            string[] files = new string[this.cDatabases];
            unsafe
            {
                for (int i = 0; i < this.cDatabases; ++i)
                {
                    files[i] = Marshal.PtrToStringAnsi(native.szDatabaseFileName[i]);
                }
            }
            this.databases = new ReadOnlyCollection(files);
        }
        /// 
        /// Set the properties of the object from a native instance info where the
        /// strings in the NATIVE_INSTANCE_INFO are Unicode.
        /// 
        /// The native instance info.
        internal void SetFromNativeUnicode(NATIVE_INSTANCE_INFO native)
        {
            this.hInstanceId = new JET_INSTANCE { Value = native.hInstanceId };
            this.szInstanceName = Marshal.PtrToStringUni(native.szInstanceName);
            this.cDatabases = checked((int)native.cDatabases);
            string[] files = new string[this.cDatabases];
            unsafe
            {
                for (int i = 0; i < this.cDatabases; ++i)
                {
                    files[i] = Marshal.PtrToStringUni(native.szDatabaseFileName[i]);
                }
            }
            this.databases = new ReadOnlyCollection(files);
        }
    }
}
#endif // !MANAGEDESENT_ON_WSA