using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExtensiblePortfolioSite.SDK.Plugins
{

    /// <summary>
    /// Represents a Plugin Version
    /// </summary>
    public readonly struct PluginVersion : IEquatable<PluginVersion>, IComparable<PluginVersion>
    {
        /// <summary>
        /// Major Verison Number
        /// </summary>
        public readonly UInt32 Major;
        /// <summary>
        /// Minor Version Number
        /// </summary>
        public readonly UInt32 Minor;
        /// <summary>
        /// Build Version Number
        /// </summary>
        public readonly UInt32 Build;
        /// <summary>
        /// Revision Version Number
        /// </summary>
        public readonly UInt32 Revision;


        /// <inheritdoc cref="PluginVersion"/>
        /// <param name="Major">Major Version Number</param>
        /// <param name="Minor">Minor Verison Number</param>
        public PluginVersion(UInt32 Major, UInt32 Minor)
        {
            this.Major = Major;
            this.Minor = Minor;
            this.Build = 0u;
            this.Revision = 0u;
        }
        /// <inheritdoc cref="PluginVersion"/>
        /// <param name="Major">Major Version Number</param>
        /// <param name="Minor">Minor Verison Number</param>
        /// <param name="Build">Build Version Number</param>
        public PluginVersion(UInt32 Major, UInt32 Minor, UInt32 Build)
        {
            this.Major = Major;
            this.Minor = Minor;
            this.Build = Build;
            this.Revision = 0u;
        }
        /// <inheritdoc cref="PluginVersion"/>
        /// <param name="Major">Major Version Number</param>
        /// <param name="Minor">Minor Verison Number</param>
        /// <param name="Build">Build Version Number</param>
        /// <param name="Revision">Revision Version Number</param>
        public PluginVersion(UInt32 Major, UInt32 Minor, UInt32 Build, UInt32 Revision)
        {
            this.Major = Major;
            this.Minor = Minor;
            this.Build = Build;
            this.Revision = Revision;
        }


        /// <inheritdoc cref="IComparable{PluginVersion}.CompareTo(PluginVersion)"/>
        public int CompareTo(PluginVersion other)
        {
            UInt32 c = Major - other.Major;
            if (c == 0)
            {
                c = Minor - other.Minor;
                if (c == 0)
                {
                    c = Build - other.Build;
                    if (c == 0)
                    {
                        c = Revision - other.Revision;
                    }
                }
            }

            return (int)c;
        }

        /// <inheritdoc cref="IEquatable{PluginVersion}.Equals(PluginVersion)"/>
        public bool Equals(PluginVersion other) => this.Major == other.Major && this.Minor == other.Minor && this.Build == other.Build && this.Revision == other.Revision;


        /// <inheritdoc cref="object.GetHashCode"/>
        public override int GetHashCode() => base.GetHashCode();
        /// <inheritdoc cref="object.Equals(object?)"/>
        public override bool Equals([NotNullWhen(true)] object? obj) => obj is PluginVersion other && this.Equals(other);

        /// 
        public static Boolean operator ==(PluginVersion l, PluginVersion r) => l.Equals(r);
        /// 
        public static Boolean operator !=(PluginVersion l, PluginVersion r) => !l.Equals(r);

        /// 
        public static Boolean operator >(PluginVersion l, PluginVersion r) => l.CompareTo(r) > 0;
        /// 
        public static Boolean operator <(PluginVersion l, PluginVersion r) => l.CompareTo(r) < 0;
    }
}
