package es.ejie.frmk.infraestructura.tablas;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import es.ejie.frmk.Q70Factoria;
import es.ejie.frmk.infraestructura.logs.incidencias.Q70LogIncidenciasInterface;
import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70TrazaInterface;

/**
 * @version 1.0
 * Fecha: 19-dic-03
 * 
 * Clase que permite tratar el catálogo (creación y manipulación del mismo).<br>
 * Una instancia de Catálogo tiene un parámetro, que es el nombre del catálogo<br>
 * Los métodos de esta clase permitirán añadir una tabla al catálogo, obtenerla y/o eliminarla.<br>
 */
public class Q70Catalogo {
	private HashMap tablas;
	private int maxPoolHsql=-1;
	private int minPoolHsql=-1;
	private int timeoutHsql=-1;
	private int maximoEnMemoriaAplicacion = -1;

	private int numTablasEnMemoria = 0;
	
	
	/**
	 * Construye un catálogo con el nombre especificado
	 * @param nombre nombre del catálogo a construir
	 */
	Q70Catalogo(String nombre) {
		tablas = new HashMap();		
	}

	/**
	 * Añade una tabla al catálogo
	 * @param nombre nombre de la tabla
	 * @param tabla objeto Q70tabla con toda la información de la tabla
	 */
	void addTable(String nombre,Q70Tabla tabla){
		String nombreTabla = nombre.toLowerCase();
		// comprobacion de duplicados
		if (null!=getTable(nombreTabla)){
			Q70TrazaInterface traza = Q70Factoria.getTraza();
			Q70LogIncidenciasInterface logInc = Q70Factoria.getLogIncidencias();
			
			if (traza.isTraceActive()){
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "Se esta intentando añadir una tabla al catalogo con el nombre logico '"+nombreTabla+"', el cual ya existe en el catalogo");
			}		
			if (logInc.isEnabled())
				logInc.log(new Q70GestorTablasException(this.getClass().getName(), "addTable", "Se esta intentando añadir una tabla al catalogo con el nombre logico '"+nombreTabla+"', el cual ya existe en el catalogo",null));
		}
		else{
			tablas.put(nombreTabla,tabla);
			if (Q70Constantes.cierto.equalsIgnoreCase(String.valueOf(tabla.getInMem()))){
				numTablasEnMemoria++;
			}
		}
	}
	
	/**
	 * Borra una tabla del catálogo
	 * @param nombre nombre de la tabla a borrar
	 */
	protected void removeTable(String nombre){
		tablas.remove(nombre.toLowerCase());
		numTablasEnMemoria--;
	}
	
	/**
	 * Obtiene una tabla a partir de su nombre
	 * @param nombre nombre de la tabla que se quiere obtener
	 * @return un objeto Q70Tabla
	 */
	Q70Tabla getTable(String nombre){
		return (Q70Tabla)tablas.get(nombre.toLowerCase());
		
	}
	
	/**
	 * Obtiene todas las tablas del catálogo cargadas en memoria y su datasource
	 * @return un objeto hashmap con el nombre de la tabla y su datasource
	 */
	HashMap getInfoLoadedTables(){
		HashMap hm = new HashMap();
		Iterator it = tablas.entrySet().iterator();
		Map.Entry e;
		String nTabla;
		Q70Tabla tabla;
		String datasource;
		while (it.hasNext()){
			e = (Map.Entry)it.next();
			nTabla = (String)e.getKey();
			tabla = (Q70Tabla)e.getValue();
			if (tabla.getLoaded()){
				datasource = tabla.getDatasource();
				hm.put(nTabla,datasource);			
			}
		}
		return hm;
	}
	
	/**
	 * Obtiene las tablas cargadas en memoria
	 * @return ArrayList compuesto por las tablas cargadas en memoria
	 */
	ArrayList getLoadedTables(){
		ArrayList al = new ArrayList();
		Iterator it = tablas.entrySet().iterator();
		Map.Entry e;
		String nTabla;
		Q70Tabla tabla;
		while (it.hasNext()){
			e = (Map.Entry)it.next();
			nTabla = (String)e.getKey();
			tabla = (Q70Tabla)e.getValue();
			if (tabla.getLoaded()){
				al.add(new Q70DescripcionTabla(nTabla));
			}
		}
		return al;
	}
	
	/**
	 * Obtiene el tamaño máximo del pool de hypersonic
	 * @return int
	 */
	int getMaxPoolHsql() {
		return maxPoolHsql;
	}

	/**
	 * Obtiene el tamaño mínimo del pool de hypersonic
	 * @return int
	 */
	int getMinPoolHsql() {
		return minPoolHsql;
	}

	/**
	 * Obtiene el tiempo de timeout para hypersonic
	 * @return int
	 */
	int getTimeoutHsql() {
		return timeoutHsql;
	}

	/**
	 * Establece el tamaño máximo del pool para hypersonic
	 * @param valor tamaño máximo del pool
	 */
	void setMaxPoolHsql(int valor) {
		maxPoolHsql = valor;
	}

	/**
	 * Establece el tamaño mínimo del pool para hypersonic
	 * @param valor tamaño mínimo del pool
	 */
	void setMinPoolHsql(int valor) {
		minPoolHsql = valor;
	}

	/**
	 * Establece el tiempo de timeout para hypersonic
	 * @param valor tiempo de timeout
	 */
	void setTimeoutHsql(int valor) {
		timeoutHsql = valor;
	}

	/**
	 * Obtiene las tablas del catalogo
	 * @return hashmap
	 */
	public Map getTablas() {
		return Collections.unmodifiableMap(tablas);
	}

	/**
	 * Establece las tablas del catálogo
	 * @param tablas hashmap de tablas
	 */
	void setTablas(HashMap tablas) {
		this.tablas = tablas;
	}

	/**
	 * Obtiene el máximo número de tablas que van a
	 * poder cargarse en memoria para una aplicación 
	 * @return int
	 */
	int getMaximoEnMemoriaAplicacion() {
		return maximoEnMemoriaAplicacion;
	}

	/**
	 * Establece el máximo número de tablas que van a poder cargarse 
	 * en memoria para una aplicación
	 * @param valor número de tablas
	 */
	void setMaximoEnMemoriaAplicacion(int valor) {
		this.maximoEnMemoriaAplicacion = valor;
	}

	/**
	 * Obtiene el numero de tablas cargadas en memoria.
	 * @return int 
	 */	
	int getNumTablasEnMemoria() {
		return numTablasEnMemoria;
	}
	
}
