/*
 * 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.axis2.jaxws.handler;

import org.apache.axiom.soap.RolePlayer;
import org.apache.axiom.soap.SOAP11Constants;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPConstants;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.util.LoggingControl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.namespace.QName;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.soap.SOAPHandler;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/*
 * Utility class to perform static utility type of operations on Handlers.
 */
public class HandlerUtils {
    private static Log log = LogFactory.getLog(HandlerUtils.class);

    /**
     * registerHandlerHeaders will invoke getHeaders on SOAPHandlers and return a List of headers
     * that are Understood by the handlers.
     * @param msgContext
     * @param handlers
     */
    public static List<QName> registerSOAPHandlerHeaders(MessageContext msgContext, List<Handler> handlers){
    	List<QName> understood = new ArrayList<QName>();
        if(msgContext == null){
            return understood;
        }

        for(Handler handler:handlers){
            if(handler instanceof SOAPHandler){
                SOAPHandler soapHandler = (SOAPHandler)handler;
                //Invoking getHeaders.
                if(log.isDebugEnabled()){
                    log.debug("Invoking getHeader() on SOAPHandler");
                }
                Set<QName> headers = soapHandler.getHeaders();
                if(headers!=null){
                    for(QName header:headers){
                        if(!understood.contains(header)){
                            if(log.isDebugEnabled()){
                                log.debug("Adding Header QName" + header + " to uderstoodHeaderQName List");
                            }
                            //Adding this to understood header list.
                            understood.add(header);
                        }
                    }
                }
            }
        }
        return understood;
    }

    /**
     * checkMustUnderstand will validate headers that where delegated by Axis Engine
     * to MessageReceiver for mustUnderstand check.
     * 
     * Note that there is other JAX-WS related mustUnderstand checking occuring elsewhere:
     * @see org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher 
     * @see org.apache.axis2.jaxws.dispatchers.MustUnderstandChecker 
     * 
     * @param msgContext Contains the SOAPEnvelope and optionally a list of headers not 
     *    understood by the AxisEngine
     * @param understood A list of header QNames understood by JAX-WS, for example those understood
     *   by associated application handlers. Can be null.
     * @param additionalRoles An instance of RolePlayer for any addtional roles played by JAX-WS
     *   for example, roles configured for associated handlers.  Can be null.
     * 
     * @throws AxisFault if any headers marked mustUndersand are not understood.
     */
    public static void checkMustUnderstand(MessageContext msgContext, List<QName> understood, List<String> additionalRoles) throws AxisFault {
        if (msgContext == null || !msgContext.isHeaderPresent()) {
            return;
        }
        SOAPEnvelope envelope = msgContext.getEnvelope();
        if (envelope.getHeader() == null) {
            return;
        }
        
        if(log.isDebugEnabled()){
            log.debug("Reading UnprocessedHeaderNames from Message Context properties");
        }
 
        List<QName> unprocessed = (List)msgContext.getProperty(Constants.UNPROCESSED_HEADER_QNAMES);

        // Add to the unprocessed header list any headers that are unprocssed and mustUnderstand
        // for addtional roles, for example those played by associated JAXWS handlers
        if (additionalRoles != null) {
            if (log.isDebugEnabled()) {
                log.debug("Adding any mustUnderstand headers based on additonal SOAP roles: " + additionalRoles);
            }
            HandlerRolePlayer handlerRolePlayer = new HandlerRolePlayer(additionalRoles);
            Iterator headerBlocks = envelope.getHeader().getHeadersToProcess(handlerRolePlayer);
            while (headerBlocks.hasNext()) {
                SOAPHeaderBlock shb = (SOAPHeaderBlock) headerBlocks.next();
                if (unprocessed == null) {
                    unprocessed = new ArrayList<QName>();
                }
                if (!shb.isProcessed() && shb.getMustUnderstand()) {
                    unprocessed.add(shb.getQName());
                    if (log.isDebugEnabled()) {
                        log.debug("Added header to unprocessed list: " + shb.getQName());
                    }
                }
            }
        }
        
        if(unprocessed == null || unprocessed.size() == 0){
            if(log.isDebugEnabled()){
                log.debug("UNPROCESSED_HEADER_QNAMES not found.");
            }
            return;
        }
        
        //lets go thru each header only if @HandlerChain is present
        if(!canUnderstand(msgContext)){
            QName[] qNames = unprocessed.toArray(new QName[0]);
            String[] headerNames = new String[qNames.length];
            for(int i=0; i<qNames.length; i++){
                headerNames[i] ="{" + qNames[i].getNamespaceURI()+ "}" + qNames[i].getLocalPart();
            }
            QName faultQName = envelope.getVersion().getMustUnderstandFaultCode();
            throw new AxisFault(Messages.getMessage("mustunderstandfailed2", headerNames), faultQName); 
        }

        checkUnprocessed(envelope, unprocessed, understood, msgContext);
        //resetting the FAULTY_HEADER_QNAME to null.
        msgContext.setProperty(Constants.UNPROCESSED_HEADER_QNAMES, null);
    }

    private static void checkUnprocessed(SOAPEnvelope envelope, List<QName> unprocessed, List<QName> understood, MessageContext msgContext) throws AxisFault{
        for (QName headerQName : unprocessed) {           
            if (understood != null && !understood.isEmpty()) {
                if (understood.contains(headerQName)) {
                    if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled()) {
                        log.debug("MustUnderstand header registered as understood on AxisOperation: " + headerQName);
                    }    
                    continue;
                }
            }
            if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled()) {
                log.debug("MustUnderstand header not processed or registered as understood " + headerQName);
            }
            // Throw a MustUnderstand fault for the current SOAP version
            String prefix = envelope.getNamespace().getPrefix();
            if (!msgContext.isSOAP11()) {
                if (prefix == null || "".equals(prefix)) {
                    prefix = SOAPConstants.SOAP_DEFAULT_NAMESPACE_PREFIX;
                }
                // TODO: should we be using a prefix on the faultcode?  What about
                // the QName object Constants.FAULT_SOAP12_MUSTUNDERSTAND?
                throw new AxisFault(Messages.getMessage("mustunderstandfailed",
                    prefix,
                    headerQName.toString()),
                    SOAP12Constants.FAULT_CODE_MUST_UNDERSTAND);
            } else {
                // TODO: should we be using a prefix on the faultcode?  What about
                // the QName object Constants.FAULT_MUSTUNDERSTAND?
                throw new AxisFault(Messages.getMessage("mustunderstandfailed",
                    prefix,
                    headerQName.toString()),
                    SOAP11Constants.FAULT_CODE_MUST_UNDERSTAND);
            }
        }
    }

    private static boolean canUnderstand(MessageContext msgContext){
        //JAXWSMessageReceiver will only commit to handling must understand if @HandlerChain annotation is present on the
        //Endpoint. This will indicate to AxisEngine that Faulty Header names are understood however the mustUnderstand 
        //Check will be performed in HandlerUtils class after Handlers are injected in application.
        AxisService axisSvc = msgContext.getAxisService();
        if (axisSvc.getParameter(EndpointDescription.AXIS_SERVICE_PARAMETER) != null) {
            Parameter param = axisSvc.getParameter(EndpointDescription.AXIS_SERVICE_PARAMETER);
            EndpointDescription ed = (EndpointDescription)param.getValue();
            //Lets check if there is a Handler implementation present using Metadata layer.
            //HandlerChain annotation can be present in Service Endpoint or ServiceEndpointInterface.
            // ed.getHandlerChain() looks for HandlerAnnotation at both Endpoint and at SEI.
            if(log.isDebugEnabled()){
                log.debug("Check to see if a jaxws handler is configured.");
            }
            if(ed.getHandlerChain()!=null){
                return true;
            }
            return false;
        }
        else{
            //If we cannot get to ServiceDescription to check for HandlerChain annotation we will return true;
            return true;
        }

    }
}
class HandlerRolePlayer implements RolePlayer {
    List<String> roles = new ArrayList<String>();

    HandlerRolePlayer(List<String> additionalRoles) {
        roles.addAll(additionalRoles);
    }
    public List getRoles() {
        return roles;
    }
    public boolean isUltimateDestination() {
        return false;
    }
}

