package com.ejie.ab04b.webservice.util;

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.ab04b.constantes.Constantes;
import com.ejie.ab04b.util.seguridad.UtilSeguridad;

/**
 * Handler de cliente que añade el token de seguridad al mesage SOAP
 * 
 * @author GFI_NORTE
 * 
 */
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();
	}

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

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

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

	/**
	 * Handle message.
	 *
	 * @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;
				// crear token n38 de aplicacion
				Document token = UtilSeguridad.getInstance().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);

				// 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;
	}
}
