package es.ejie.frmk.listeners.base;

import java.util.Locale;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.util.RequestUtils;

import es.ejie.frmk.control.arranque.Q70GestorArranqueConfiguracion;
import es.ejie.frmk.infraestructura.logs.base.Q70DatosComunes;
import es.ejie.frmk.infraestructura.logs.base.Q70GestorLogs;
import es.ejie.frmk.infraestructura.logs.base.interfaces.Q70GestorDatosComunes;
import es.ejie.frmk.infraestructura.logs.base.interfaces.Q70LogServidorInterface;
import es.ejie.frmk.infraestructura.seguridad.Q70GestorSeguridad;
import es.ejie.frmk.infraestructura.seguridad.Q70InformacionSeguridadUsuario;
import es.ejie.frmk.infraestructura.seguridad.Q70SeguridadException;
import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70Traza;
import es.ejie.frmk.presentacion.base.Q70Constantes;
import es.ejie.frmk.presentacion.operacion.Q70DatosOPConfig;
import es.ejie.frmk.presentacion.operacion.Q70DatosOPPlugIn;
import es.ejie.frmk.presentacion.operacion.Q70LogicaOperacionDePresentacion;
import es.ejie.frmk.presentacion.sesiondatos.Q70ContextoEJIE;
import es.ejie.frmk.presentacion.sesiondatos.Q70SesionDatos;

public class Q70LogDataUtils {

	/**
	 * Instancia del log de trazas
	 */
	private static Q70Traza tr = Q70Traza.getSingleton();
	
	
	/**
	 * Método que prepara los datos necesarios para el componente de Logs.
	 * 
	 * @param <code>HttpServletRequest</code>.
	 * @param canal Canal al que pertenece dicha petición
	 * @param componente Componente que invoca a este método
	 */
	public static void processPrepareLogData(HttpServletRequest request, String canal, String componente)
	{
		initialPrepareLogData(request, canal ,componente);
		finalPrepareLogData(request, componente);
	}

	/**
	 * Método que inicia la preparación de los datos necesarios para el
	 * componente de Logs.
	 * 
	 * @param <code>HttpServletRequest</code>.
	 * @param canal Canal al que pertenece dicha petición
	 * @param componente Componente que invoca a este método
	 */
	public static void initialPrepareLogData(HttpServletRequest request, String canal, String componente)
	{
		try {
			if (tr.isTraceActive())
			{
				tr.trace(componente, Q70TraceLevel.INFO, "Preparando información para Logs.");
			}
		
			Q70LogServidorInterface logManager = Q70GestorLogs.getSingleton().getComponenteAplicacion();
			Q70GestorDatosComunes dataManager = logManager.getCommonDataManager();
			Q70DatosComunes data = dataManager.getData();
	
			String op = RequestUtils.getModuleName(request, request.getSession().getServletContext());
			if (0 == op.length())
			{
				op = Q70LogicaOperacionDePresentacion.DEFAULT_OP;
			}
			data.setCodigoOperacion(op.substring(1));
			
			String aplicacion = (String)request.getSession().getServletContext().getInitParameter(Q70GestorArranqueConfiguracion.NOMBRE_APLICACION);
			data.setAplicacion(aplicacion);
			
			try
			{
				data.setNumeroOperacion((String)((Q70DatosOPConfig)request.getSession().getServletContext().getAttribute(Q70DatosOPPlugIn.DATOSOP_KEY+op)).getNumero());
			}
			catch(Exception e)
			{
				data.setNumeroOperacion(op);
			}
	
			Q70ContextoEJIE contexto = (Q70ContextoEJIE) request.getSession().getAttribute(Q70Constantes.CONTEXT);
			if (null != contexto)
			{
				obtenerInfomacionUsuario(data, contexto);
			}
	
			data.setCodigoPais(Locale.getDefault().getCountry());
			data.setCanal(canal);
			data.setIdSesion(request.getSession().getId());
		
			int indexAncho = request.getRequestURI().lastIndexOf("/");
			data.setCodigoPagina(indexAncho<0?request.getRequestURI():request.getRequestURI().substring(indexAncho+1));
			data.setNumeroPagina(indexAncho<0?request.getRequestURI():request.getRequestURI().substring(indexAncho+1));
			
			dataManager.setData(data);
		} catch (RuntimeException e) {
			if (tr.isTraceActive())
			{
				tr.trace(componente, Q70TraceLevel.WARN, "MODO DEPURACIÓN.");
			}
			//No genero una frameworkException ya que es un warning que indica
			//que estamos en modo depuración.
		}
	}

	/**
	 * Método que finaliza la preparación de los datos necesarios para el
	 * componente de Logs.
	 * 
	 * @param <code>HttpServletRequest</code>.
	 * @param componente Componente que invoca a este método
	 */
	public static void finalPrepareLogData(HttpServletRequest request, String componente)
	{
		try {
			//Recuperación de contexto
			Q70ContextoEJIE contexto = (Q70ContextoEJIE) request.getSession().getAttribute(Q70Constantes.CONTEXT);
		
			Q70LogServidorInterface logManager = Q70GestorLogs.getSingleton().getComponenteAplicacion();
			Q70GestorDatosComunes dataManager = logManager.getCommonDataManager();
			Q70DatosComunes data = dataManager.getData();
		
			String op = RequestUtils.getModuleName(request, request.getSession().getServletContext());
			if (0 == op.length())
			{
				op = Q70LogicaOperacionDePresentacion.DEFAULT_OP;
			}
			data.setCodigoOperacion(op);
			
			String aplicacion = (String)request.getSession().getServletContext().getInitParameter(Q70GestorArranqueConfiguracion.NOMBRE_APLICACION);
			data.setAplicacion(aplicacion);
			
			try
			{
				data.setNumeroOperacion((String)((Q70DatosOPConfig)request.getSession().getServletContext().getAttribute(Q70DatosOPPlugIn.DATOSOP_KEY+op)).getNumero());
			}
			catch(Exception e)
			{
				data.setNumeroOperacion(op);
			}
			if (null != contexto)
			{
				obtenerInfomacionUsuario(data, contexto);
			}
			dataManager.setData(data);
		} catch (RuntimeException e) {
			if (tr.isTraceActive())
			{
				tr.trace(componente, Q70TraceLevel.WARN, "MODO DEPURACIÓN.");
			}
			//No genero una frameworkException ya que es un warning que indica
			//que estamos en modo depuración.
		}
	}

	/**
	 * Método que borra los datos para el componente de Logs.
	 */
	public static void clearLogData (String componente)
	{
		try {
			if (tr.isTraceActive())
			{
				tr.trace(componente, Q70TraceLevel.INFO, "Eliminando información para Logs.");
			}
			
			Q70LogServidorInterface logManager = Q70GestorLogs.getSingleton().getComponenteAplicacion();
			Q70GestorDatosComunes dataManager = logManager.getCommonDataManager();
			dataManager.clearData();
		} catch (RuntimeException e) {
			if (tr.isTraceActive())
			{
				tr.trace(componente, Q70TraceLevel.WARN, "MODO DEPURACIÓN.");
			}
			//No genero una frameworkException ya que es un warning que indica
			//que estamos en modo depuración.
		}
	}

	/**
	 * Obtiene la informacion del usuario que se va a asociar al hilo de ejecucion
	 * 
	 * @param data
	 * @param contexto
	 */
	private static void obtenerInfomacionUsuario(Q70DatosComunes data, Q70ContextoEJIE contexto) {
		Q70InformacionSeguridadUsuario informacionSeguridadUsuario = (Q70InformacionSeguridadUsuario)contexto.get(es.ejie.frmk.infraestructura.seguridad.Q70Constantes.SEGURIDAD_USUARIO);
		try {
			data.setCodigoEntidad(Q70GestorSeguridad.getSingleton().getSessionEntity(informacionSeguridadUsuario));
		} catch (Q70SeguridadException e1) {
			data.setCodigoEntidad("N/A");
		}
//		try {
//			data.setIdUsuario(Q70GestorSeguridad.getSingleton().getSessionId(informacionSeguridadUsuario));
//		} 
//		catch (Q70SeguridadException e2) {
//			data.setIdUsuario("N/A");
//		}
		//En el contexto de sesion, se guarda como identificativo el id de usuario de xl-nets,
		// y se trata de un usuario anonimo entonces el id anonimo.
		data.setIdUsuario(Q70SesionDatos.getSingleton().getContexto(contexto,Q70SesionDatos.CTX_SESION_USUARIO).getIdContexto());
	}
}
