package com.ejie.aa21b.ws.handler;

import java.util.HashSet;
import java.util.Set;

import javax.xml.namespace.QName;
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 n38a.exe.N38APISesion;

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

import com.ejie.aa21b.util.Aa21bConstantes;

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();
	}

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

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

	public boolean handleFault(SOAPMessageContext context) {
		return true;
	}

	public boolean handleMessage(SOAPMessageContext context) {
		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 = Aa21bConstantes.AA21B_CODAPP;

				// crear token n38 de aplicacion
				N38APISesion n38Sesion = new N38APISesion();
				Document token = n38Sesion
						.n38APISesionCrearApp(codigoAplicacion);

				// recuperar cabecera SOAP
				SOAPHeader soapHeader = context.getMessage().getSOAPHeader();

				// 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(e.getMessage());
				StackTraceElement[] elements = e.getStackTrace();
				for (StackTraceElement err : elements)
					N38TokenClientHandler.logger.error(err.toString());
			}
		}
		return valid;
	}

}
