/*
 * 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.servicemix.camel.nmr.ws.addressing;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.SoapVersion;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.ws.addressing.AddressingProperties;
import org.apache.cxf.ws.addressing.AttributedURIType;
import org.apache.cxf.ws.addressing.ContextUtils;
import org.apache.cxf.ws.addressing.Names;
import org.apache.cxf.ws.addressing.soap.VersionTransformer;
import org.apache.cxf.ws.addressing.v200408.AttributedURI;

import static org.apache.cxf.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES_INBOUND;
import static org.apache.cxf.ws.addressing.JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_OUTBOUND;


/**
 * Verifies presence of expected SOAP headers.
 */
public class HeaderVerifier extends AbstractSoapInterceptor {
    VerificationCache verificationCache = new GreeterImpl();
    String currentNamespaceURI;
    
    public HeaderVerifier() {
        super(Phase.POST_PROTOCOL);
    }
    
    public Set<QName> getUnderstoodHeaders() {
        return Names.HEADERS;
    }

    public void handleMessage(SoapMessage message) {
        mediate(message);
    }

    public void handleFault(SoapMessage message) {
        mediate(message);
    }
    
    private void mediate(SoapMessage message) {
        boolean outgoingPartialResponse = isOutgoingPartialResponse(message);
        if (outgoingPartialResponse) {
            addPartialResponseHeader(message);
        }
        verify(message, outgoingPartialResponse);
    }

    private void addPartialResponseHeader(SoapMessage message) {
        try {
            // add piggybacked wsa:From header to partial response
            List<Header> header = message.getHeaders();
            Document doc = DOMUtils.createDocument();
            SoapVersion ver = message.getVersion();
            Element hdr = doc.createElementNS(ver.getHeader().getNamespaceURI(), 
                ver.getHeader().getLocalPart());
            hdr.setPrefix(ver.getHeader().getPrefix());
            
            marshallFrom("urn:piggyback_responder", hdr, getMarshaller());
            NodeList nl = hdr.getChildNodes();
            for (int i = 0; i < nl.getLength(); i++) {
                Object obj = nl.item(i);
                if (obj instanceof Element) {
                    Element elem = (Element) obj;
                    Header holder = new Header(
                            new QName(elem.getNamespaceURI(), elem.getLocalName()), 
                            elem, null);
                    header.add(holder);
                }
            }
            
        } catch (Exception e) {
            verificationCache.put("SOAP header addition failed: " + e);
            e.printStackTrace();
        }
    }

    private void verify(SoapMessage message, boolean outgoingPartialResponse) {
        try {
            List<String> wsaHeaders = new ArrayList<String>();
            List<Header> headers = message.getHeaders();
            if (headers != null) {
                recordWSAHeaders(headers,
                                 wsaHeaders,
                                 Names.WSA_NAMESPACE_NAME);
                recordWSAHeaders(headers,
                                 wsaHeaders,
                                 VersionTransformer.Names200408.WSA_NAMESPACE_NAME);
                recordWSAHeaders(headers,
                                 wsaHeaders,
                                 WSAddressingTest.CUSTOMER_NAME.getNamespaceURI());
            }
            boolean partialResponse = isIncomingPartialResponse(message)
                                      || outgoingPartialResponse;
            verificationCache.put(WSAddressingTest.verifyHeaders(wsaHeaders, 
                                                        partialResponse,
                                                        isRequestLeg(message)));
        } catch (SOAPException se) {
            verificationCache.put("SOAP header verification failed: " + se);
        }
    }

    private void recordWSAHeaders(List<Header> headers,
                                  List<String> wsaHeaders,
                                  String namespaceURI) {
        Iterator<Header> iter = headers.iterator();
        while (iter.hasNext()) {
            Object obj = iter.next().getObject();
            if (obj instanceof Element) {
                Element hdr = (Element) obj;
                if (namespaceURI.equals(hdr.getNamespaceURI())) {
                    if (namespaceURI.endsWith("addressing")) {
                        currentNamespaceURI = namespaceURI;
                        wsaHeaders.add(hdr.getLocalName());
                    } else if (WSAddressingTest.CUSTOMER_NAME.getNamespaceURI().equals(namespaceURI)) {
                        String headerText = hdr.getTextContent();
                        if (WSAddressingTest.CUSTOMER_KEY.equals(headerText)) {
                            wsaHeaders.add(hdr.getLocalName());
                        }
                    }
                }
            }
            
        }
    }

    private boolean isRequestLeg(SoapMessage message) {
        return (ContextUtils.isRequestor(message) && ContextUtils.isOutbound(message))
               || (!ContextUtils.isRequestor(message) && !ContextUtils.isOutbound(message));     
    }

    private boolean isOutgoingPartialResponse(SoapMessage message) {
        AddressingProperties maps = 
            (AddressingProperties)message.get(SERVER_ADDRESSING_PROPERTIES_OUTBOUND);
        return ContextUtils.isOutbound(message)
               && !ContextUtils.isRequestor(message)
               && maps != null
               && Names.WSA_ANONYMOUS_ADDRESS.equals(maps.getTo().getValue());
    }
    
    private boolean isIncomingPartialResponse(SoapMessage message) 
        throws SOAPException {
        AddressingProperties maps = 
            (AddressingProperties)message.get(CLIENT_ADDRESSING_PROPERTIES_INBOUND);
        return !ContextUtils.isOutbound(message)
               && ContextUtils.isRequestor(message)
               && maps != null
               && Names.WSA_ANONYMOUS_ADDRESS.equals(maps.getTo().getValue());
    }
    
    private Marshaller getMarshaller() throws JAXBException {
        JAXBContext jaxbContext =
            VersionTransformer.getExposedJAXBContext(currentNamespaceURI);
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        return marshaller;
    }

    private void marshallFrom(String from, Element header, Marshaller marshaller) 
        throws JAXBException {
        if (Names.WSA_NAMESPACE_NAME.equals(currentNamespaceURI)) {
            String u = "urn:piggyback_responder";
            AttributedURIType value =
                org.apache.cxf.ws.addressing.ContextUtils.getAttributedURI(u);
            marshaller.marshal(
                new JAXBElement<AttributedURIType>(Names.WSA_FROM_QNAME,
                                                   AttributedURIType.class,
                                                   value),
                header);
        } else if (VersionTransformer.Names200408.WSA_NAMESPACE_NAME.equals(
                                                      currentNamespaceURI)) {
            AttributedURI value =
                VersionTransformer.Names200408.WSA_OBJECT_FACTORY.createAttributedURI();
            value.setValue(from);
            QName qname = new QName(VersionTransformer.Names200408.WSA_NAMESPACE_NAME, 
                                    Names.WSA_FROM_NAME);
            marshaller.marshal(
                new JAXBElement<AttributedURI>(qname,
                                               AttributedURI.class,
                                               value),
                header);
        }                                                                    
    }
    
    public void setVerificationCache(VerificationCache cache) {
        verificationCache = cache;
    }
    
    
}


