package com.ejie.y42b.utils;

import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Date;

import com.ejie.y42b.constantes.Y42bAgendaConstantes;

/**
 * Genera GUID en 32 bytes
 * 
 *  
 * 
 */
public class Y42bUIDGenerator32 {
	private SecureRandom sRandom = null;
	private MessageDigest md = null;
	private static final Object monitor = new Object();
	private static Y42bUIDGenerator32 instance;

	/**
	 * 
	 * @return getInstance
	 */
	public static Y42bUIDGenerator32 getInstance() {
		synchronized (Y42bUIDGenerator32.monitor) {
			if (Y42bUIDGenerator32.instance == null) {
			    Y42bUIDGenerator32.instance = new Y42bUIDGenerator32();
			}
			return Y42bUIDGenerator32.instance;
		}
	}

	/**
	 * 
	 */
	private Y42bUIDGenerator32() {
		this.sRandom = new SecureRandom();
		this.sRandom.nextLong();
		try {
			this.md = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Generated GUID 40 caracteres
	 * @return generatedId
	 */
	public String generateId() {
		long timeStampLong = new Date().getTime();
		int objectHashCode = System.identityHashCode(this);
		long secureInt = this.sRandom.nextLong();

		String result = Long.toHexString(timeStampLong) + Integer.toHexString(objectHashCode) + Long.toHexString(secureInt);

		byte[] resultSha = this.md.digest(result.getBytes());
		StringBuffer strBuff = new StringBuffer();

		for (int i = 0; i < resultSha.length; ++i) {
			strBuff.append(this.toHexString(resultSha[i]));
		}
		return strBuff.toString();
	}

	/**
	 * 
	 * @param b b
	 * @return hex
	 */
	private String toHexString(byte b) {

		final int frm = 0x7F;
		final int bits = Y42bAgendaConstantes.NUM_128;
		final int word = Y42bAgendaConstantes.NUM_16;

		int value = (b & frm) + (b < 0 ? bits : Y42bAgendaConstantes.NUM_0);

		StringBuffer ret = new StringBuffer((value < word) ? "0" : "");
		ret.append(Integer.toHexString(value).toUpperCase());
		return ret.toString();
	}
}
