﻿/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
using System;
using System.Net;
using System.Security.Permissions;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Apache.NMS.Util;
using Apache.NMS;

namespace Apache.NMS.AMQP.Util
{
    #region Id Class

    public class Id : IComparable
    {
        public static readonly Id EMPTY = new Id();
        protected const int DEFAULT_MAX_CAPACITY = 1;
        protected static readonly int[] HashTable = new int[] { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
        protected static readonly int HashTableSize = HashTable.Length;
        protected delegate ComponentId InstanceFactory(object o);
        protected static readonly Dictionary<Type, InstanceFactory> buildMap;

        #region Class Initializer

        static Id()
        {
            buildMap = new Dictionary<Type, InstanceFactory>();
            buildMap.Add(typeof(String), (o) => { return new ComponentId<string>(o as string); });
            buildMap.Add(typeof(UInt16), (o) => { return new ComponentId<UInt16>(Convert.ToUInt16(o)); });
            buildMap.Add(typeof(UInt32), (o) => { return new ComponentId<UInt32>(Convert.ToUInt32(o)); });
            buildMap.Add(typeof(UInt64), (o) => { return new ComponentId<UInt64>(Convert.ToUInt64(o)); });
            buildMap.Add(typeof(Int16), (o) => { return new ComponentId<UInt16>(Convert.ToUInt16(o)); });
            buildMap.Add(typeof(Int32), (o) => { return new ComponentId<UInt32>(Convert.ToUInt32(o)); });
            buildMap.Add(typeof(Int64), (o) => { return new ComponentId<UInt64>(Convert.ToUInt64(o)); });
            buildMap.Add(typeof(AtomicSequence), (o) =>
            {
                ulong val = 0;
                AtomicSequence seq = o as AtomicSequence;
                if (o != null && seq != null)
                {
                    val = seq.getAndIncrement();
                }
                return new ComponentId<UInt64>(val);
            });
            buildMap.Add(typeof(Guid), (o) =>
            {
                Guid id;
                if (o == null)
                {
                    id = Guid.Empty;
                }
                else
                {
                    id = (Guid)o;
                }
                return new ComponentId<Guid>(id);
            });
            buildMap.Add(typeof(Id), (o) => { return new ComponentId<Id>(o as Id); });
        }

        #endregion

        ComponentId[] components;
        private bool isReadOnly = false;
        private int length;
        private int maxCapacity;
        private int current;
        private string componentDelimeter;
        private int hashcode = 0;

        #region Constructors

        public Id(string delimeter, int size, int maxSize)
        {
            maxCapacity = Math.Max(maxSize, DEFAULT_MAX_CAPACITY);
            length = size;
            components = new ComponentId[length];
            current = 0;
            componentDelimeter = delimeter;
        }

        public Id(int size, int maxSize) : this(IdGenerator.ID_COMPONENT_DELIMETER, size, maxSize) { }

        public Id(int size) : this(IdGenerator.ID_COMPONENT_DELIMETER, size, size) { }

        public Id(params object[] args) : this(args.Length)
        {
            int added = this.AddAll(args);
            if(added > maxCapacity)
            {
                Tracer.ErrorFormat("Id Format error.");
            }
            Generate();
        }

        #endregion

        #region Public Properties

        public int Size
        {
            get { return length; }
        }

        #endregion

        #region Public Methods

        public void Add(object component)
        {
            if (isReadOnly)
            {
                throw new NMSException("Invalid Operation when generating Component Id. Can not change id once generated.");
            }
            if (current >= maxCapacity)
            {
                throw new NMSException("Invalid Operation when generating Component Id. Can not add component. Adding Compoenent at full capacity " + maxCapacity);
            }
            if (current >= length)
            {
                grow(length * 2);
            }
            Type type = component.GetType();
            InstanceFactory instf = null;
            buildMap.TryGetValue(type, out instf);
            if (instf == null)
            {
                throw new NMSException(string.Format("Invalid Id component type {0} for component {1}", type.ToString(), component.ToString()));
            }
            components[current] = instf(component);
            current++;

        }

        public object[] GetComponents(int startIndex=0)
        {
            return GetComponents(startIndex, length);
        }

        public object[] GetComponents(int startIndex, int endIndex)
        {
            int eIndex = Math.Max(0,Math.Min(endIndex, length));
            int sIndex = Math.Max(0, startIndex);
            int resultLen = eIndex - sIndex;
            if (resultLen<0)
            {
                return null;
            }
            object[] comps = new object[resultLen];
            int index = 0;
            for(int i=sIndex; i< eIndex; i++)
            {
                comps[index] = components[i].IdValue;
                index++;
            }
            return comps;
        }

        public object GetComponent(int index)
        {
            if (isReadOnly)
            {
                if (index >= 0 && index < length)
                {
                    return components[index].IdValue;
                }
            }
            return null;
        }

        public object GetFirstComponent(Type type)
        {
            if (isReadOnly)
            {
                for (int i = 0; i < length; i++)
                {
                    ComponentId cid = components[i];
                    if (cid.ValueType.Equals(type))
                    {
                        return cid.IdValue;
                    }
                }
            }
            return null;
        }

        public object GetLastComponent(Type type)
        {
            if (isReadOnly)
            {
                for (int i = length; i > 0; i--)
                {
                    ComponentId cid = components[i - 1];
                    if (cid.ValueType.Equals(type))
                    {
                        return cid.IdValue;
                    }
                }
            }
            return null;
        }

        public void Generate()
        {
            if (!isReadOnly)
            {
                isReadOnly = true;
                this.GetHashCode();
            }
        }

        #endregion

        #region Object Override Methods

        public override bool Equals(object obj)
        {
            if(GetHashCode() == obj.GetHashCode())
            {
                return true;
            }
            else
            {
                return CompareTo(obj) == 0;
            }
        }

        public override int GetHashCode()
        {
            if(hashcode == 0 && isReadOnly && length > 0)
            {
                int hashIndex = 0;
                ComponentId cid = components[0];
                hashcode = HashTable[hashIndex] * cid.GetHashCode();
                for (int i=1; i<length; i++)
                {
                    cid = components[i];
                    hashIndex = i % HashTableSize;
                    hashcode = hashcode ^ HashTable[hashIndex] * cid.GetHashCode(); 
                }
            }
            return hashcode;
        }

        public override string ToString()
        {
            if (maxCapacity == 0)
            {
                return "0";
            }
            if (isReadOnly)
            {
                if (length == 0)
                {
                    return EMPTY.ToString();
                }
                StringBuilder sb = new StringBuilder();
                ComponentId cid = this.components[0];
                sb.Append(cid.ToString());
                for (int i = 1; i < length; i++)
                {
                    cid = this.components[i];
                    sb.Append(componentDelimeter);
                    sb.Append(cid.ToString());
                    
                }
                return sb.ToString();
            }
            else
            {
                return base.ToString();
            }
        }

        #endregion

        #region IComparable Methods

        public int CompareTo(object obj)
        {

            if(obj!=null && obj is Id)
            {
                return CompareTo(obj as Id);
            }
            else if(obj == null)
            {
                return 1;
            }
            else
            {
                return -1;
            }

        }

        public int CompareTo(Id that)
        {
            if(this.length > that.length)
            {
                return 1;
            }
            else if (this.length < that.length)
            {
                return -1;
            }
            else
            {
                int compare = 0;
                for(int i=0; i<length; i++)
                {
                    ComponentId thisCid = this.components[i];
                    ComponentId thatCid = that.components[i];
                    compare = thisCid.CompareTo(thatCid);
                    if ( compare > 0)
                    {
                        return 1;
                    }
                    else if ( compare < 0 )
                    {
                        return -1;
                    }

                }
                return compare;
            }
        }

        #endregion

        #region Protected Methods

        protected void grow(int newCapacity)
        {
            int size = Math.Min(newCapacity, maxCapacity);
            ComponentId[] buffer = new ComponentId[size];
            Array.Copy(this.components, buffer, this.length);
            length = size;
            this.components = buffer;
        }

        protected int AddAll(params object[] args)
        {
#if NET46
            if(Tracer.IsDebugEnabled)
            {
                Tracer.DebugFormat("Adding Id components: {0} MaxCapacity: {1}", string.Join(",",
                          args.Select(x => x.ToString()).ToArray()), maxCapacity);

            }
#else
#endif
            int added = 0;
            foreach (object o in args)
            {
                Type type = o.GetType();

                if (type.IsArray && type.Equals(typeof(object[])))
                {
                    object[] moreArgs = o as object[];
                    int addlen = (moreArgs).Length;

                    maxCapacity = maxCapacity + addlen - 1;
                    added += this.AddAll(moreArgs);

                }
                else
                {
                    this.Add(o);
                    added++;
                }
            }
            return added;
        }

#endregion

#region Inner ComponentId Classes

        protected abstract class ComponentId : IComparable
        {
            protected object value;

            protected ComponentId(object idvalue)
            {
                value = idvalue;
            }

            public object IdValue { get { return value; } }

            public abstract Type ValueType { get; }

            public virtual int CompareTo(object obj)
            {
                if(obj == null)
                {
                    return 1;
                }
                else if(obj is ComponentId)
                {
                    return CompareTo(obj as ComponentId);
                }
                else if (obj is IComparable)
                {
                    return -1 * (obj as IComparable).CompareTo(this.IdValue);
                }
                else
                {
                    return -1;
                }
            }

            public virtual int CompareTo(ComponentId that)
            {
                if (this.ValueType.Equals(that.ValueType) || this.ValueType.IsEquivalentTo(that.ValueType))
                {
                    if (this.IdValue.Equals(that.IdValue))
                    {
                        return 0;
                    }
                    else
                    {
                        return this.GetHashCode() - that.GetHashCode();
                    }
                }
                else if (this.IdValue is IComparable)
                {
                    return (this.IdValue as IComparable).CompareTo(that.IdValue);
                }
                else if (that.IdValue is IComparable)
                {
                    return -1 * (that.IdValue as IComparable).CompareTo(this.IdValue);
                }
                else
                {
                    return this.ValueType.GetHashCode() - that.ValueType.GetHashCode();
                }
                
            }

            public override bool Equals(object obj)
            {
                return CompareTo(obj) == 0;
            }


            public override int GetHashCode()
            {
                return this.IdValue.GetHashCode();
            }

            public override string ToString()
            {
                return value.ToString();
            }
        }
        
        protected class ComponentId<T> : ComponentId
        {
            public ComponentId(T val) : base(val)
            {
            }

            public T Value
            {
                get { return (T)this.value; }
            }

            public override Type ValueType
            {
                get
                {
                    if (value != null)
                    {
                        return value.GetType();
                    }
                    return default(T).GetType();
                }
            }
        }

#endregion

    }

#endregion

#region IdGenerator Class

    public class IdGenerator
    {
        public const string ID_COMPONENT_DELIMETER = ":";
        protected static readonly string DEFAULT_PREFIX = "ID";
        protected static string hostname = null;

        protected readonly string prefix;
        protected readonly AtomicSequence sequence = new AtomicSequence(1);

#region Class Initializer

        static IdGenerator()
        {
#if NETSTANDARD2_0
            hostname = Dns.GetHostName();
#else
            DnsPermission permissions = null;
            try
            {
                permissions = new DnsPermission(PermissionState.Unrestricted);
            }
            catch (Exception e)
            {
                Tracer.InfoFormat("{0}", e.StackTrace);
            }
            if (permissions != null)
            {
                hostname = Dns.GetHostName();
            }
#endif

        }

#endregion

#region Constructors

        public IdGenerator(string prefix)
        {
            this.prefix = RemoveEnd(prefix, ID_COMPONENT_DELIMETER)
                + ((hostname == null)
                    ?
                    ""
                    :
                    ID_COMPONENT_DELIMETER + hostname)
                ;
        }

        public IdGenerator() : this(DEFAULT_PREFIX)
        {
        }

#endregion

        public virtual Id GenerateId()
        {
            Id id = new Id(this.prefix, Guid.NewGuid(), sequence);
            return id;
        }

        public virtual string generateID()
        {
            Id id = GenerateId();
            return id.ToString();
            //return string.Format("{0}{1}" + ID_COMPONENT_DELIMETER + "{2}", this.prefix, Guid.NewGuid().ToString(), sequence.getAndIncrement());
        }

        protected static string RemoveEnd(string s, string end)
        {
            string result = s;

            if (s != null && end != null && s.EndsWith(end))
            {
                int sLen = s.Length;
                int endLen = end.Length;
                int newLen = sLen - endLen;
                if (endLen > 0 && newLen > 0)
                {
                    StringBuilder sb = new StringBuilder(s, 0, newLen, newLen);
                    result = sb.ToString();
                }
            }
            return result;
        }
    }

#endregion

#region Derivative IdGenerator Classes

    class NestedIdGenerator : IdGenerator
    {
        protected Id parentId;
        protected bool removeParentPrefix;

        public NestedIdGenerator(string prefix, Id pId, bool remove) : base(prefix)
        {
            parentId = pId;
            removeParentPrefix = remove;
        }

        public NestedIdGenerator(string prefix, Id pId) : this(prefix, pId, false) { }

        public NestedIdGenerator(Id pId):this(DEFAULT_PREFIX, pId) { }

        public override Id GenerateId()
        {
            Id id;
            if (removeParentPrefix)
            {
                int componentIndex = (parentId.Size == 1) ? 0 : 1;
                id = new Id(prefix, parentId.GetComponents(componentIndex), sequence);
            }
            else
            {
                id = new Id(prefix, parentId, sequence);
            }
            
            return id;
        }

        public override string generateID()
        {
            return GenerateId().ToString();
        }
    }

    class CustomIdGenerator : IdGenerator
    {
        protected object[] parts;
        protected bool isOnlyParts;


        public CustomIdGenerator(string prefix, params object[] args) : base(prefix)
        {
            parts = args;
        }

        public CustomIdGenerator(bool onlyParts, params object[] args) : this(DEFAULT_PREFIX, args)
        {
            isOnlyParts = onlyParts;
        }

        public CustomIdGenerator(Id pId) : this(DEFAULT_PREFIX, pId) { }

        public override Id GenerateId()
        {
            Id id;
            if (isOnlyParts)
            {
                id = new Id(parts);
            }
            else
            {
                id = new Id(prefix, parts, sequence);
            }
            return id;
        }

        public override string generateID()
        {
            return GenerateId().ToString();
        }
    }

#endregion
}
