package es.ejie.frmk.conectores.conectorJDBC;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import es.ejie.frmk.infraestructura.logs.base.Q70DatosComunes;

/**
 * Clase base que contiene la información necesaria para monitorizar los thread activos en los diferentes clusters.
 * La clase implementa toda la logica de serialización para enviar y leer la información de los clusters.
 * La información serializada es:
 * <ul>
 * <li>Nombre del Thread </li> 
 * <li>Hora de activacion </li>
 * <li>Clase con informacion extra (Q70DatosComunes): id del usuario, codigo del pais, canal, etc... </li>
 * <li>Numero de conexiones abiertas por el thread </li>
 * <li>Numero de conexiones cerradas por el thread </li>
 * </ul>
 * La información que no se serializa a causa de que son clases que incorporan la característica synchronized son:
 * <ul>
 * <li> El thread actual. Tipo Thread </li>
 * <li> Lista de conexiones del thread. Tipo Connection /li> 
 * </ul>
 * @version 1.0     Fecha: 10-mar-04
 */
public class Q70DatosDeThread implements Externalizable
{
	private static final long serialVersionUID = 1L;

	private String nameThread = null; 
	private transient Thread thread; 
	private Date horaActivacion;
	private Q70DatosComunes datosComunes;
	private transient List listaConexiones;
	private Integer conexionesAbiertas=null;
	private Integer conexionesCerradas=null;

	/**
	 * Constructor Inicializa la lista de conexiones
	 */
	public Q70DatosDeThread(){
		super();
		listaConexiones = new ArrayList(5);
	}
	
	/**
	 * Constructor. Inicializa el thread, los datos comunes, la lista de conexiones y la hora de activación
	 * @param aThread
	 * @param aDatosComunes
	 * @param aListaConexiones
	 */
	public Q70DatosDeThread(Thread aThread, Q70DatosComunes aDatosComunes, List aListaConexiones)
	{
		super();
		thread = aThread;
		datosComunes = aDatosComunes;
		listaConexiones = aListaConexiones;
		horaActivacion = new Date();
	}
	
	/**
	 * Constructor. Inicializa el  nombre del thread, el thread, los datos comunes,la lista de conexiones y la 
	 * hora de activación
	 * @param nameThread
	 * @param aThread
	 * @param aDatosComunes
	 * @param aListaConexiones
	 */
	public Q70DatosDeThread(String nameThread,Thread aThread, Q70DatosComunes aDatosComunes, List aListaConexiones)
	{
		super();
		this.nameThread=nameThread;
		thread = aThread;
		datosComunes = aDatosComunes;
		listaConexiones = aListaConexiones;
		horaActivacion = new Date();
	}
	
	
	/**
	 * @return thread
	 */
	Thread getThread()
	{
		return thread;
	}

	/**
	 * @return datosComunes
	 */
	public Q70DatosComunes getDatosComunes()
	{
		return datosComunes;
	}
	
	/**
	 * @param datosComunes
	 */
	public void setDatosComunes(Q70DatosComunes datosComunes)
	{
		this.datosComunes = datosComunes;
	}

	/**
	 * @return horaActivacion
	 */
	public Date getHoraActivacion()
	{
		return horaActivacion;
	}
	
	/**
	 * @param horaActivacion
	 */
	public void setHoraActivacion(Date horaActivacion)
	{
		this.horaActivacion = horaActivacion;
	}

	/**
	 * @return listaConexiones
	 */
	public List getListaConexiones()
	{
		return listaConexiones;
	}

	/**
	 * @param nameThread
	 */
	public void setNameThread (String nameThread)
	{
		this.nameThread = nameThread;
	}
	
	/**
	 * @return nameThread
	 */
	public String getNameThread ()
	{ 
		return this.nameThread;
	}
	
	
	/**
	 * Escribe los datos a serializar
	 * @param ou
	 */
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeObject(getNameThread());
		out.writeObject(getHoraActivacion());
		out.writeObject(getDatosComunes());
		calculoConexiones(out);
	}
	
	/**
	 * Calcula el numero de conexiones abiertas y cerradas y las serializa
	 * @param out
	 * @throws IOException
	 */
	private synchronized void calculoConexiones(ObjectOutput out) throws IOException {
		
		int abiertas=0;
		int cerradas=0;
		Connection connection = null;
		
		for (int i=0;i<listaConexiones.size();i++){
			connection = (Connection)listaConexiones.get(i);
			 
			try {
				if(connection!=null && !connection.isClosed())
					abiertas++;
				else
					cerradas++;
			} catch (SQLException e) {
				throw new IOException ();
			}
		}
		out.writeObject(new Integer(abiertas));
		out.writeObject(new Integer(cerradas));
	}
	
	/**
	 * Recupera los parametros serializados
	 * @param is
	 * @throws IOException, ClassNotFoundException
	 */
	public void readExternal(ObjectInput is) throws IOException, ClassNotFoundException {
		setNameThread((String) is.readObject());
		setHoraActivacion((Date) is.readObject());
		setDatosComunes((Q70DatosComunes)is.readObject());
		setConexionesAbiertas((Integer)is.readObject());
		setConexionesCerradas((Integer)is.readObject());
	}
	
	/**
	 * @param conexionesAbiertas
	 */
	private void setConexionesAbiertas(Integer conexionesAbiertas) {
		this.conexionesAbiertas=conexionesAbiertas;
	}
	
	/**
	 * @return conexionesAbiertas
	 */
	public Integer getConexionesAbiertas(){
		return this.conexionesAbiertas;
	}
	
	/**
	 * @param conexionesCerradas
	 */
	private void setConexionesCerradas(Integer conexionesCerradas) {
		this.conexionesCerradas=conexionesCerradas;
	}
	
	/**
	 * @return conexionesCerradas
	 */
	public Integer getConexionesCerradas(){
		return this.conexionesCerradas;
	}
}
