package com.ejie.m62fb.ws.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.m62fb.utils.constants.AppConstantes;

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

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

	private final TransformerFactory transformerFactory;

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

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

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

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

	/**
	 * @param context
	 *            SOAPMessageContext
	 * @return boolean
	 */
	@Override
	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 codAplicacion = AppConstantes.APLICACION;
				Document token = N38TokenUtil.getTokenAppXLNets(codAplicacion);

				// 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);
				valid = true;
			} catch (Exception e) {
				N38TokenClientHandler.logger.error(
						"Ha ocurrido un error al capturar el mensaje Soap", e);
			}

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