package com.ejie.ab39a.model.handler;

import java.util.HashSet;

import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

import com.ejie.ab39a.constantes.Constantes;
import com.ejie.ab39a.utils.UtilXML;
import com.ejie.ab39a.seguridad.UtilSeguridad;

/**
 * Handler de cliente que añade el token de seguridad al mesage SOAP
 * 
 *  
 * 
 */
public class N38TokenClientHandler implements SOAPHandler<SOAPMessageContext> {

	private static final Logger logger = LoggerFactory.getLogger(N38TokenClientHandler.class);

	private TransformerFactory transformerFactory;

	/**
	 * Constructor por defecto
	 */
	public N38TokenClientHandler() {
		this.transformerFactory = TransformerFactory.newInstance();
	}

	/**
	 * @return Set
	 */
	public Set<QName> getHeaders() {
		return new HashSet<QName>();
	}

	/**
	 * @param context
	 *            MessageContext
	 */
	public void close(MessageContext context) {
		// Nada que hacer
	}

	/**
	 * @param context
	 *            SOAPMessageContext
	 * @return boolean
	 */
	public boolean handleFault(SOAPMessageContext context) {
		return true;
	}

	/**
	 * @param context
	 *            SOAPMessageContext
	 * @return boolean
	 */
	public boolean handleMessage(SOAPMessageContext context) {
		N38TokenClientHandler.logger.debug("handleMessage INI");
		boolean valid = true;
		Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

		// solo para los mensajes SALIENTES
		if (outbound != null && outbound.booleanValue()) {
			valid = false;

			try {
				// recuperar codigo de aplicacion de configuracion
				String codigoAplicacion = Constantes.APLICACION;
				Document token = UtilSeguridad.getTokenDocumentXLNets(codigoAplicacion);
				// recuperar cabecera SOAP
				SOAPHeader soapHeader = context.getMessage().getSOAPHeader();

				// Si la cabecera es nula, la creamos
				if (soapHeader == null) {
					SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
					soapHeader = envelope.addHeader();
				}
				// incluir token en la cabecera creada
				Source source = new DOMSource(token);
				Result result = new DOMResult(soapHeader);
				this.transformerFactory.newTransformer().transform(source, result);
				String strTemp = UtilXML.parseDocument2String(context.getMessage().getSOAPBody().getOwnerDocument());
				N38TokenClientHandler.logger.debug("Mensaje Soap saliente: ".concat(strTemp != null ? strTemp : ""));
				// se puede continuar el procesamiento
				valid = true;

			} catch (Exception e) {
				N38TokenClientHandler.logger.error("Se ha producido un error: ", e);
			}

		} // fin del if
		N38TokenClientHandler.logger.debug("handleMessage FIN - resultado: " + valid);
		return valid;
	}
}
