// Copyright © Selmo Technology GmbH. All Rights Reserved

using System.Diagnostics.Contracts;
using System.Diagnostics;
using System.Globalization;
using Novus.Shared.Id;

namespace SelmoStudio.Hmi.Server.SelmoHmi.Notification.Model.Ids
{
    /// <summary>
    /// Strong typed id <see cref="NotificationConfigurationId"/>.
    /// </summary>
    [DebuggerDisplay("{DebuggerDisplay,nq}")]
    public struct NotificationConfigurationId :
        IEquatable<NotificationConfigurationId>, IGuidBasedId
    {
        private readonly int _cachedHashCode;

        /// <summary>
        /// Wrapped Guid.
        /// </summary>
        public Guid Guid { get; }

        /// <summary>
        /// Creates new instance.
        /// </summary>
        public NotificationConfigurationId(Guid guid)
        {
            Guid = guid;
            _cachedHashCode = Guid.GetHashCode();
        }

        /// <summary>
        /// Returns a string that represents the current instance. To upper makes string equatable.
        /// </summary>
        /// <returns>A string that represents the current instance.</returns>
        [Pure]
        public override string ToString()
        {
            return Guid.ToString("B", CultureInfo.InvariantCulture).ToUpperInvariant();
        }

        /// <summary>
        /// Returns the hash code for the current instance.
        /// </summary>
        /// <returns>A 32-bit signed integer hash code.</returns>
        [Pure]
        public override int GetHashCode()
        {
            return _cachedHashCode;
        }

        /// <summary>
        /// Determines whether the specified instance is equal to the current instance.
        /// </summary>
        /// <param name="other">The instance to compare with the current instance.</param>
        /// <returns>True, if the specified instance is equal to the current instance; otherwise, False.</returns>
        [Pure]
        public override bool Equals(object other)
        {
            return other is NotificationConfigurationId && Equals((NotificationConfigurationId)other);
        }

        /// <summary>
        /// Determines whether the specified instance is equal to the current instance.
        /// </summary>
        /// <param name="other">The instance to compare with the current instance.</param>
        /// <returns>True, if the specified instance is equal to the current instance; otherwise, False.</returns>
        [Pure]
        public bool Equals(NotificationConfigurationId other)
        {
            if (_cachedHashCode != other._cachedHashCode)
                return false;

            return Guid.Equals(other.Guid);
        }

        /// <summary>
        /// Determines whether the specified instances are equal.
        /// </summary>
        /// <param name="a">The first instance to compare.</param>
        /// <param name="b">The second instance to compare.</param>
        /// <returns>True, if the specified instances are equal; otherwise, False.</returns>
        [Pure]
        public static bool operator ==(NotificationConfigurationId a,
            NotificationConfigurationId b)
        {
            return a.Equals(b);
        }

        /// <summary>
        /// Determines whether the specified instances are unequal.
        /// </summary>
        /// <param name="a">The first instance to compare.</param>
        /// <param name="b">The second instance to compare.</param>
        /// <returns>True, if the specified instances are unequal; otherwise, False.</returns>
        [Pure]
        public static bool operator !=(NotificationConfigurationId a, NotificationConfigurationId b)
        {
            return !a.Equals(b);
        }

        /// <summary>
        /// This member serves the infrastructure and is not intended to be used directly.
        /// </summary>
        internal string DebuggerDisplay => ToString();
    }
}