/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.ode.axis2.hooks;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.handlers.AbstractHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.ode.axis2.ODEService;
import org.apache.ode.utils.DOMUtils;
import org.apache.ode.utils.Namespaces;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.namespace.QName;

/**
 * An incoming handler adding session id information in the message
 * context.
 */
public class SessionInHandler extends AbstractHandler {
    private static final long serialVersionUID = -806564877582696569L;

    private static final Logger __log = LoggerFactory.getLogger(SessionInHandler.class);

    public InvocationResponse invoke(MessageContext messageContext) throws AxisFault {
        SOAPHeader header = messageContext.getEnvelope().getHeader();
        if (header != null) {
            if (__log.isDebugEnabled())
                __log.debug("Found a header in incoming message, checking if there are endpoints there.");
            // Checking if a session identifier has been provided for a stateful endpoint
            OMElement wsaToSession = header.getFirstChildWithName(new QName(Namespaces.ODE_SESSION_NS, "session"));
            if (wsaToSession == null) {
                wsaToSession = header.getFirstChildWithName(new QName(Namespaces.INTALIO_SESSION_NS, "session"));
            }
            if (wsaToSession != null) {
                // Building an endpoint supposed to target the right instance
                Document doc = DOMUtils.newDocument();
                Element serviceEpr = doc.createElementNS(Namespaces.WS_ADDRESSING_NS, "EndpointReference");
                Element intSessionId = doc.createElementNS(Namespaces.INTALIO_SESSION_NS, "session");
                Element odeSessionId = doc.createElementNS(Namespaces.ODE_SESSION_NS, "session");
                doc.appendChild(serviceEpr);
                serviceEpr.appendChild(intSessionId);
                serviceEpr.appendChild(odeSessionId);
                intSessionId.setTextContent(wsaToSession.getText());
                odeSessionId.setTextContent(wsaToSession.getText());
                if (__log.isDebugEnabled())
                    __log.debug("A TO endpoint has been found in the header with session: " + wsaToSession.getText());

                // Did the client provide an address too?
                OMElement wsaToAddress = header.getFirstChildWithName(new QName(Namespaces.WS_ADDRESSING_NS, "To"));
                if (wsaToAddress != null) {
                    Element addressElmt = doc.createElementNS(Namespaces.WS_ADDRESSING_NS, "Address");
                    addressElmt.setTextContent(wsaToAddress.getText());
                    serviceEpr.appendChild(addressElmt);
                }
                if (__log.isDebugEnabled())
                    __log.debug("Constructed a TO endpoint: " + DOMUtils.domToString(serviceEpr));
                messageContext.setProperty(ODEService.TARGET_SESSION_ENDPOINT, serviceEpr);
            }

            // Seeing if there's a callback, in case our client would be stateful as well
            OMElement callback = header.getFirstChildWithName(new QName(Namespaces.ODE_SESSION_NS, "callback"));
            if (callback == null) {
                callback = header.getFirstChildWithName(new QName(Namespaces.INTALIO_SESSION_NS, "callback"));
            }
            if (callback != null) {
                OMElement callbackSession = callback.getFirstChildWithName(new QName(Namespaces.ODE_SESSION_NS, "session"));
                if(callbackSession==null){
                    callbackSession = callback.getFirstChildWithName(new QName(Namespaces.INTALIO_SESSION_NS, "session"));
                }
                if (callbackSession != null) {
                    // Building an endpoint that represents our client (we're supposed to call him later on)
                    Document doc = DOMUtils.newDocument();
                    Element serviceEpr = doc.createElementNS(Namespaces.WS_ADDRESSING_NS, "EndpointReference");
                    Element intSessionId = doc.createElementNS(Namespaces.INTALIO_SESSION_NS, "session");
                    Element odeSessionId = doc.createElementNS(Namespaces.ODE_SESSION_NS, "session");
                    doc.appendChild(serviceEpr);
                    serviceEpr.appendChild(intSessionId);
                    serviceEpr.appendChild(odeSessionId);
                    intSessionId.setTextContent(callbackSession.getText());
                    odeSessionId.setTextContent(callbackSession.getText());
                    if (__log.isDebugEnabled())
                        __log.debug("A CALLBACK endpoint has been found in the header with session: " + callbackSession.getText());

                    // Did the client give his address as well?
                    OMElement wsaToAddress = callback.getFirstChildWithName(new QName(Namespaces.WS_ADDRESSING_NS, "Address"));
                    if (wsaToAddress != null) {
                        Element addressElmt = doc.createElementNS(Namespaces.WS_ADDRESSING_NS, "Address");
                        addressElmt.setTextContent(wsaToAddress.getText());
                        serviceEpr.appendChild(addressElmt);
                    }
                    if (__log.isDebugEnabled())
                        __log.debug("Constructed a CALLBACK endpoint: " + DOMUtils.domToString(serviceEpr));
                    messageContext.setProperty(ODEService.CALLBACK_SESSION_ENDPOINT, serviceEpr);
                }
            }
        }
        return InvocationResponse.CONTINUE;
    }

}
