package de.tu_dresden.diplom.richter_mirko_mat2628335.common.handler;

import org.apache.log4j.Logger;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.MessageContext;
import org.apache.axis.Message;
import org.apache.axis.AxisFault;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.axis.message.SOAPHeaderElement;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.handler.data.IFHandlingInfo;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.handler.data.HandlingInfo;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.NS;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.Constants;

import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;

/**
 * First abstraction-layer for between axis-hanlders an the prototype
 */
public abstract class BaseHandler extends BasicHandler {

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

   public static final String CONTEXT_ACTOR = "http://diplom.compago.de/soap/actor/acp";
   public static final String CONTEXT_COORDINATION_TYPE = "http://diplom.compago.de/2005/03/acp";

   public static final String OPTION_LOG_INFO = "logInfo";

   private static ThreadLocal handlingInfos = new ThreadLocal();

   /**
    * Gets the current handlingInfo aout of the ThreadLocal-object
    * @return
    */
   public static IFHandlingInfo getHandlingInfo() {
      final String fn = "[getHandlingInfo]";
      IFHandlingInfo result = (IFHandlingInfo) handlingInfos.get();
      if (result == null) {
         result = new HandlingInfo();
         handlingInfos.set(result);
      }
//      if(messageContext != null){
//         result = (IFHandlingInfo) messageContext.getProperty(PROP_HANDLING_INFO);
//         if(result == null){
//            if (logger.isDebugEnabled()) logger.debug(fn + " initializing handlingInfo");
//            result = new HandlingInfo();
//            messageContext.setProperty(PROP_HANDLING_INFO, result);
//         }else{
//            if (logger.isDebugEnabled()) logger.debug(fn + " handlingInfo already existant");
//         }
//      }else{
//         logger.error(fn + " messageContext was NULL!");
//      }
      return result;
   }

   /**
    * Removes the handlingInfo from the current thread.
    */
   public static void removeHandlingInfo() {
      handlingInfos.remove();
   }

   /**
    * Creates the Basic-Structure of the XML-Representation of an CountinContext-Element within
    * the given SOAP-Envelope
    * @param soapEnvelope The envelope into which the Element should be inserted
    * @throws SOAPException
    */
   protected void createCountingContextInSOAPHeader(SOAPEnvelope soapEnvelope) throws SOAPException {
      final String fn = "[createCountingContextInSOAPHeader]";
      logger.debug(fn + " setting SOAP-Default-Values for our context-object");
      //soapEnvelope.addNamespaceDeclaration("wscoor", WS_COORDINATION_NAMESPACE);
      //soapEnvelope.addNamespaceDeclaration("wsu", WS_UTILITY_NAMESPACE);
      //soapEnvelope.addNamespaceDeclaration("acp", ACCESS_CONTROL_PROTOTYP_NAMESPACE);
      SOAPHeader soapHeader = soapEnvelope.getHeader();
      SOAPHeaderElement contextHead = new SOAPHeaderElement(NS.ACCESS_CONTROL_PROTOTYP_NAMESPACE, Constants.ELEMENT_NAME_COUNTING_CONTEXT);
      contextHead.setMustUnderstand(true);
      contextHead.addNamespaceDeclaration(NS.WS_COORDINATION_PREFIX, NS.WS_COORDINATION_NAMESPACE);
      contextHead.addNamespaceDeclaration(NS.WS_UTILITY_PREFIX, NS.WS_UTILITY_NAMESPACE);
      contextHead.addNamespaceDeclaration(NS.ACCESS_CONTROL_PROTOTYP_PREFIX, NS.ACCESS_CONTROL_PROTOTYP_NAMESPACE);
      contextHead.setActor(CONTEXT_ACTOR);
      soapHeader.addChildElement(contextHead);
   }

   /**
    * Returns the Element out of the message that represents a SOAP-Body-Element (used
    * to create/validate Signatures on that Element)
    * @param message Message to extract the Element from
    * @return The Element if found, NULL else
    * @throws Exception
    */
   public static Element getBodyElement(Message message) throws Exception {
      SOAPEnvelope soapEnvelope = message.getSOAPEnvelope();
      Document doc = soapEnvelope.getAsDocument();
      Element envelope = doc.getDocumentElement();
      NodeList bodies = envelope.getElementsByTagNameNS(NS.SOAP_ENVELOPE_NAMESPACE, "Body");
      Element body = (Element) bodies.item(0);
      return body;
   }
}
