/*
 * 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.Net.Sockets;
using System.Threading;

namespace Apache.NMS.Stomp.Util
{
    public class IdGenerator
    {
        private static String UNIQUE_STUB;
        private static int instanceCount;
        private static String hostName;
        private String seed;
        private long sequence;

        static IdGenerator()
        {
            String stub = "-1-" + DateTime.Now.Ticks;
            hostName = "localhost";

            try
            {
                hostName = Dns.GetHostName();
                IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
                Socket tempSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                tempSocket.Bind(endPoint);
                stub = "-" + ((IPEndPoint)tempSocket.LocalEndPoint).Port + "-" + DateTime.Now.Ticks + "-";
                Thread.Sleep(100);
                tempSocket.Close();
            }
            catch(Exception ioe)
            {
                Tracer.Warn("could not generate unique stub: " + ioe.Message);
            }

            UNIQUE_STUB = stub;
        }

        /**
         * Construct an IdGenerator
         */
        public IdGenerator(String prefix)
        {
            lock(UNIQUE_STUB)
            {
                this.seed = prefix + UNIQUE_STUB + (instanceCount++) + ":";
            }
        }

        public IdGenerator() : this("ID:" + hostName)
        {
        }

        /// <summary>
        /// As we have to find the hostname as a side-affect of generating a unique
        /// stub, we allow it's easy retrevial here
        /// </summary>
        public static String HostName
        {
            get { return hostName; }
        }

        /// <summary>
        /// Generate a Unique Id
        /// </summary>
        /// <returns>
        /// A <see cref="String"/>
        /// </returns>
        public String GenerateId()
        {
            lock(UNIQUE_STUB)
            {
                return this.seed + (this.sequence++);
            }
        }

        /// <summary>
        /// Generate a unique ID - that is friendly for a URL or file system
        /// </summary>
        /// <returns>
        /// A <see cref="String"/>
        /// </returns>
        public String GenerateSanitizedId()
        {
            String result = GenerateId();
            result = result.Replace(':', '-');
            result = result.Replace('_', '-');
            result = result.Replace('.', '-');
            return result;
        }

        /// <summary>
        /// From a generated id - return the seed (i.e. minus the count)
        /// </summary>
        /// <param name="id">
        /// A <see cref="String"/>
        /// </param>
        /// <returns>
        /// A <see cref="String"/>
        /// </returns>
        public static String GetSeedFromId(String id)
        {
            String result = id;

            if(id != null)
            {
                int index = id.LastIndexOf(':');
                if(index > 0 && (index + 1) < id.Length)
                {
                    result = id.Substring(0, index + 1);
                }
            }

            return result;
        }

        /// <summary>
        /// From a generated id - return the generator count
        /// </summary>
        /// <param name="id">
        /// A <see cref="String"/>
        /// </param>
        /// <returns>
        /// A <see cref="System.Int64"/>
        /// </returns>
        public static long GetSequenceFromId(String id)
        {
            long result = -1;
            if(id != null)
            {
                int index = id.LastIndexOf(':');

                if(index > 0 && (index + 1) < id.Length)
                {
                    String numStr = id.Substring(index + 1, id.Length);
                    result = Int64.Parse(numStr);
                }
            }
            return result;
        }

        /// <summary>
        /// Does a proper compare on the ids
        /// </summary>
        /// <param name="id1">
        /// A <see cref="String"/>
        /// </param>
        /// <param name="id2">
        /// A <see cref="String"/>
        /// </param>
        /// <returns>
        /// A <see cref="System.Int32"/>
        /// </returns>
        public static int Compare(String id1, String id2)
        {
            int result = -1;

            String seed1 = IdGenerator.GetSeedFromId(id1);
            String seed2 = IdGenerator.GetSeedFromId(id2);

            if(seed1 != null && seed2 != null)
            {
                result = seed1.CompareTo(seed2);

                if(result == 0)
                {
                    long count1 = IdGenerator.GetSequenceFromId(id1);
                    long count2 = IdGenerator.GetSequenceFromId(id2);
                    result = (int)(count1 - count2);
                }
            }

            return result;
        }
    }
}
