/*
 * Copyright 1999,2006 The Apache Software Foundation.
 * 
 * Licensed 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 org.apache.catalina.tribes.util;

import java.security.SecureRandom;
import java.util.Random;

/**
 * simple generation of a UUID 
 * @author Filip Hanik
 * @version 1.0
 */
public class UUIDGenerator {
    public static final int UUID_LENGTH = 16;
    public static final int UUID_VERSION = 4;
    public static final int BYTES_PER_INT = 4;
    public static final int BITS_PER_BYTE = 8;
    
    protected static SecureRandom secrand = null;
    protected static Random rand = new Random(System.currentTimeMillis());
    static {
        secrand = new SecureRandom();
        secrand.setSeed(rand.nextLong());
    }
    
    public static byte[] randomUUID(boolean secure) {
        byte[] result = new byte[UUID_LENGTH];
        return randomUUID(secure,result,0);
    }

    public static byte[] randomUUID(boolean secure, byte[] into, int offset) {
        if ( (offset+UUID_LENGTH)>into.length )
            throw new ArrayIndexOutOfBoundsException("Unable to fit "+UUID_LENGTH+" bytes into the array. length:"+into.length+" required length:"+(offset+UUID_LENGTH));
        Random r = (secure&&(secrand!=null))?secrand:rand;
        nextBytes(into,offset,UUID_LENGTH,r);
        into[6+offset] &= 0x0F;
        into[6+offset] |= (UUID_VERSION << 4);
        into[8+offset] &= 0x3F; //0011 1111
        into[8+offset] |= 0x80; //1000 0000
        return into;
    }
    
    /**
     * Same as java.util.Random.nextBytes except this one we dont have to allocate a new byte array
     * @param into byte[]
     * @param offset int
     * @param length int
     * @param r Random
     */
    public static void nextBytes(byte[] into, int offset, int length, Random r) {
        int numRequested = length;
        int numGot = 0, rnd = 0;
        while (true) {
            for (int i = 0; i < BYTES_PER_INT; i++) {
                if (numGot == numRequested) return;
                rnd = (i == 0 ? r.nextInt() : rnd >> BITS_PER_BYTE);
                into[offset+numGot] = (byte) rnd;
                numGot++;
            }
        }
    }

}