/*
 * 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.
 */
package flex.messaging.util;

import java.util.Random;
import java.util.UUID;

public class UUIDUtils
{
    private static Random _weakRand = new Random();
	
    /**
     * The spec indicates that our time value should be based on 100 nano
     * second increments but our time granularity is in milliseconds.
     * The spec also says we can approximate the time by doing an increment
     * when we dole out new ids in the same millisecond.  We can fit 10,000
     * 100 nanos into a single millisecond.
     */
    private static final int MAX_IDS_PER_MILLI = 10000;
	
    /**
     *  Any given time-of-day value can only be used once; remember the last used
     *  value so we don't reuse them.
     *  <p>NOTE: this algorithm assumes the clock will not be turned back.
     */
    private static long lastUsedTOD = 0;
    /** Counter to use when we need more than one id in the same millisecond. */
    private static int numIdsThisMilli = 0;
	
    /**  Hex digits, used for padding UUID strings with random characters. */
    private static final String alphaNum = "0123456789ABCDEF";
	
    /** 4 bits per hex character. */
    private static final int BITS_PER_DIGIT = 4;
	
    private static final int BITS_PER_INT = 32;
    private static final int BITS_PER_LONG = 64;
    private static final int DIGITS_PER_INT = BITS_PER_INT / BITS_PER_DIGIT;
    private static final int DIGITS_PER_LONG = BITS_PER_LONG / BITS_PER_DIGIT;
	
    /**
     *  @private
     */
    private static char[] UPPER_DIGITS = new char[] {
	'0', '1', '2', '3', '4', '5', '6', '7',
	'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
    };
	
    /**
     * Private constructor to prevent instances from being created.
     */
    private UUIDUtils()
    {
    }
	
    /**
     *
     * Use the createUUID function when you need a unique string that you will
     * use as a persistent identifier in a distributed environment. To a very
     * high degree of certainty, this function returns a unique value; no other
     * invocation on the same or any other system should return the same value.
     *
     * @return a Universally Unique Identifier (UUID)
     * Proper Format: `XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
     * where `X' stands for a hexadecimal digit (0-9 or A-F).
     */
    public static String createUUID()
    {
		return createUUID(false);
	}
	
    public static String createUUID(boolean secure) throws Error
    {
        Random rand = _weakRand;
		if (secure)
			throw new Error("Secure UUIDs not implemented");
		
        StringBuffer s = new StringBuffer(36);
		
        appendHexString(uniqueTOD(), false, 11, s);
		
        //  Just use random padding characters, but ensure that the high bit
        //  is set to eliminate chances of collision with an IEEE 802 address.
        s.append(  alphaNum.charAt( rand.nextInt(16) | 8 ) );
		
        //  Add random padding characters.
        appendRandomHexChars(32 - s.length(), rand, s);
		
        //insert dashes in proper position. so the format matches CF
        s.insert(8,"-");
        s.insert(13,"-");
        s.insert(18,"-");
        s.insert(23,"-");
		
        return s.toString();
    }

    /**
     * Converts a 128-bit UID encoded as a byte[] to a String representation.
     * The format matches that generated by createUID. If a suitable byte[]
     * is not provided, null is returned.
     *
     * @param ba byte[] 16 bytes in length representing a 128-bit UID.
     *
     * @return String representation of the UID, or null if an invalid
     * byte[] is provided.
     */
    public static String fromByteArray(byte[] ba)
    {
        if (ba == null || ba.length != 16)
            return null;

        StringBuffer result = new StringBuffer(36);
        for (int i = 0; i < 16; i++)
        {
            if (i == 4 || i == 6 || i == 8 || i == 10)
                result.append('-');

            result.append(UPPER_DIGITS[(ba[i] & 0xF0) >>> 4]);
            result.append(UPPER_DIGITS[(ba[i] & 0x0F)]);
        }
        return result.toString();
    }

	
    /**
     * A utility method to check whether a String value represents a
     * correctly formatted UID value. UID values are expected to be
     * in the format generated by createUID(), implying that only
     * capitalized A-F characters in addition to 0-9 digits are
     * supported.
     *
     * @param uid The value to test whether it is formatted as a UID.
     *
     * @return Returns true if the value is formatted as a UID.
     */
    public static boolean isUID(String uid)
    {
        if (uid == null || uid.length() != 36)
            return false;

        char[] chars = uid.toCharArray();
        for (int i = 0; i < 36; i++)
        {
            char c = chars[i];

            // Check for correctly placed hyphens
            if (i == 8 || i == 13 || i == 18 || i == 23)
            {
                if (c != '-')
                    return false;
            }
            // We allow capital alpha-numeric hex digits only
            else if (c < 48 || c > 70 || (c > 57 && c < 65))
            {
                return false;
            }
        }

        return true;
    }

    /**
     * Converts a UID formatted String to a byte[]. The UID must be in the
     * format generated by createUID, otherwise null is returned.
     *
     * @param uid String representing a 128-bit UID.
     *
     * @return byte[] 16 bytes in length representing the 128-bits of the
     * UID or null if the uid could not be converted.
     */
    public static byte[] toByteArray(String uid)
    {
        if (!isUID(uid))
            return null;

        byte[] result = new byte[16];
        char[] chars = uid.toCharArray();
        int r = 0;

        for (int i = 0; i < chars.length; i++)
        {
            if (chars[i] == '-')
                continue;
            int h1 = Character.digit(chars[i], 16);
            i++;
            int h2 = Character.digit(chars[i], 16);
            result[r++] = (byte)(((h1 << 4) | h2) & 0xFF);
        }
        return result;
    }

    private static void appendRandomHexChars(int n, Random rand, StringBuffer result)
    {
        int digitsPerInt = DIGITS_PER_INT;
        while (n > 0)
        {
            int digitsToUse = Math.min(n, digitsPerInt);
            n -= digitsToUse;
            appendHexString(rand.nextInt(), true, digitsToUse, result);
        }
    }

    private static void appendHexString
        (long value, boolean prependZeroes, int nLeastSignificantDigits,
         StringBuffer result)
    {
        int bitsPerDigit = BITS_PER_DIGIT;

        long mask = (1L << bitsPerDigit) - 1;

        if (nLeastSignificantDigits < DIGITS_PER_LONG)
        {
            // Clear the bits that we don't care about.
            value &= (1L << (bitsPerDigit * nLeastSignificantDigits)) - 1;
        }

        // Reorder the sequence so that the first set of bits will become the
        // last set of bits.
        int i = 0;
        long reorderedValue = 0;
        if (value == 0)
        {
            // One zero is dumped.
            i++;
        }
        else
        {
            do
            {
                reorderedValue = (reorderedValue << bitsPerDigit) | (value & mask);
                value >>>= bitsPerDigit;
                i++;
            } while (value != 0);
        }

        if (prependZeroes)
        {
            for (int j = nLeastSignificantDigits - i; j > 0; j--)
            {
                result.append('0');
            }
        }


        // Dump the reordered sequence, with the most significant character
        // first.
        for (; i > 0; i--)
        {
            result.append(alphaNum.charAt((int) (reorderedValue & mask)));
            reorderedValue >>>= bitsPerDigit;
        }
    }

    private static String createInsecureUUID()
    {
        StringBuffer s = new StringBuffer(36);

        appendHexString(uniqueTOD(), false, 11, s);

        //  Just use random padding characters, but ensure that the high bit
        //  is set to eliminate chances of collision with an IEEE 802 address.
        s.append(  alphaNum.charAt( _weakRand.nextInt(16) | 8 ) );

        //  Add random padding characters.
        appendRandomHexChars(32 - s.length(), _weakRand, s);

        //insert dashes in proper position. so the format matches CF
        s.insert(8,"-");
        s.insert(13,"-");
        s.insert(18,"-");
        s.insert(23,"-");

        return s.toString();
    }

    /**
     *  @return a time value, unique for calls to this method loaded by the same classloader.
     */
    private static synchronized long uniqueTOD()
    {
        long currentTOD = System.currentTimeMillis();

        // Clock was set back... do not hang in this case waiting to catch up.
        // Instead, rely on the random number part to differentiate the ids.
        if (currentTOD < lastUsedTOD)
            lastUsedTOD = currentTOD;

        if (currentTOD == lastUsedTOD)
        {
            numIdsThisMilli++;
            /*
             * Fall back to the old technique of sleeping if we allocate
             * too many ids in one time interval.
             */
            if (numIdsThisMilli >= MAX_IDS_PER_MILLI)
            {
                while ( currentTOD == lastUsedTOD )
                {
                    try { Thread.sleep(1); } catch ( Exception interrupt ) { /* swallow, wake up */ }
                    currentTOD = System.currentTimeMillis();
                }
                lastUsedTOD = currentTOD;
                numIdsThisMilli = 0;
            }
        }
        else
        {
            //  We have a new TOD, reset the counter
            lastUsedTOD = currentTOD;
            numIdsThisMilli = 0;
        }

        return lastUsedTOD * MAX_IDS_PER_MILLI + (long)numIdsThisMilli;
    }
}
