package com.ejie.ab61.adaptadores.service;

import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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.xml.sax.InputSource;

import com.ejie.ab61.comun.Constantes;
import com.ejie.ab61.comun.utilidades.XlnetsUtils;

/**
 * 
 *  
 * 
 */
public class X43TareasTramitacionServiceHandler implements SOAPHandler<SOAPMessageContext> {

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

	private TransformerFactory transformerFactory;

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

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

	@Override()
	public void close(MessageContext context) {

	}

	/**
	 * 
	 * @param context
	 *            SOAPMessageContext
	 * 
	 * @return boolean
	 */
	@Override()
	public boolean handleFault(SOAPMessageContext context) {
		X43TareasTramitacionServiceHandler.logger
				.error("Error cliente ws X43TareasTramitacion " + this.logging(context));
		return true;
	}

	/**
	 * 
	 * @param context
	 *            SOAPMessageContext
	 * 
	 * @return boolean
	 */
	@Override()
	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 {
				DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
				DocumentBuilder builder = factory.newDocumentBuilder();

				org.w3c.dom.Document token = builder
						.parse(new InputSource(new StringReader(XlnetsUtils.getInstance().getTokenAplicacion(false))));

				X43TareasTramitacionServiceHandler.logger
						.info("Despues de obtener el token de sesion - token.toString():" + token.toString());

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

				X43TareasTramitacionServiceHandler.logger
						.info("cliente ws X43TareasTramitacion outbound: Token inyectado al header");

				context.put("timeini", new Long(System.currentTimeMillis()));

			} catch (Exception e) {
				e.printStackTrace();
			}

		} else {

			long timeini = (Long) (context.get("timeini"));
			long timefin = System.currentTimeMillis();

			BigDecimal result = ((new BigDecimal(timefin).subtract(new BigDecimal(timeini))).divide(
					new BigDecimal(Constantes.MAGIC_NUMBER_1000), Constantes.MAGIC_NUMBER_5, BigDecimal.ROUND_FLOOR));

			X43TareasTramitacionServiceHandler.logger
					.info("cliente ws X43TareasTramitacion tiempo transcurrido de respuesta: " + result + " sg ");
		}
		return valid;

	}

	/**
	 * 
	 * @param context
	 *            SOAPMessageContext
	 * 
	 * @return String
	 */
	private String logging(SOAPMessageContext context) {
		try {
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			context.getMessage().writeTo(out);
			return new String(out.toByteArray());
		} catch (Exception e) {
			X43TareasTramitacionServiceHandler.logger.error("Error", e);
		}
		return "NO SACAMOS MENSAJE SOAP";
	}
}
