package es.ejie.frmk.control.apilamiento;

import java.security.SecureRandom;

import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70Traza;

/**
 * Clase para generar un hash aleatorio para ser usado como clave primaria en un apilamiento remoto.
 * 
 * @version 1.0
 * Fecha: 19-feb-04
 */
public class Q70Hash {
	
	/**
	 * Constante que indica el parametro de la request que contiene el hash del apilamiento 
	 * de suboperaciones provenientes de <b>Geremua v.1.0.</b> 
	 * y de operaciones que redirigen a <b>Geremua v.1.0.</b>.
	 */
	public static final String HASH_GEREMUA_V1 = "HASH";
	public static final String HASH_GEREMUA_V1_CON_IGUAL = "HASH=";
	
	/**
	 * Constante que indica el parametro de la request que contiene el hash del apilamiento 
	 * de suboperaciones provenientes de <b>Geremua v.2.0.</b> 
	 * y de operaciones que redirigen a <b>Geremua v.2.0.</b>.
	 */
	public static final String HASH_GEREMUA_V2 = "HASH_GER";
	public static final String HASH_GEREMUA_V2_CON_IGUAL = "HASH_GER=";
	
	/**
	 * Constante que indica el componente al que pertenece dicha clase. Es
	 * necesario para el uso del log de trazas.
	 */
	private static final String COMPONENTE = "OPERACION_PRESENTACION";

	/**
	 * Instancia del log de trazas
	 */
	private static Q70Traza tr = Q70Traza.getSingleton();
	
	
	/**
	 * Método que genera un hash aleatorio para ser usado como clave primaria
	 * en un apilamiento remoto.
	 * 
	 * @return Hash en forma de String.
	 * @throws Exception
	 */
	public synchronized static String generateHash() throws Exception
	{
		SecureRandom random = null;
		byte seed[] = null;	
		byte bytes[] = null;
		String hash = null;
		try
		{
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.INFO, "Generando hash para un apilamiento remoto.");
			}
			random = java.security.SecureRandom.getInstance("SHA1PRNG");
			seed = random.generateSeed(2);
			random.setSeed(seed);
			bytes = new byte[5];
			random.nextBytes(bytes);
			hash = Thread.currentThread().getName().hashCode() + (100 + Math.abs((int)bytes[0])) + (100 + Math.abs((int)bytes[1])) + (100 + Math.abs((int)bytes[2])) + (100 + Math.abs((int)bytes[3])) + (100 + Math.abs((int)bytes[4])) + String.valueOf(new java.util.Date().getTime());
			return hash;
		}	
		catch (Exception e)
		{
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Error al generar el hash para un apilamiento remoto.");
			}
			throw new Q70ApilamientoException (Q70Hash.class.toString(),"generateHash","Error al generar el hash para un apilamiento remoto.",null);
		}
	}
}