/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed 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.soap12testing.handlers;

import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.handlers.AbstractHandler;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPBody;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPFault;
import org.apache.axiom.soap.SOAPFaultCode;
import org.apache.axiom.soap.SOAPFaultNode;
import org.apache.axiom.soap.SOAPFaultReason;
import org.apache.axiom.soap.SOAPFaultRole;
import org.apache.axiom.soap.SOAPFaultText;
import org.apache.axiom.soap.SOAPFaultValue;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.apache.axiom.soap.SOAPProcessingException;

import java.util.Iterator;

public class SOAP12InFlowHandlerDefaultC extends AbstractHandler implements HeaderConstants {
    private OMNamespace attributeNS;
    private boolean attributePresent = false;
    Integer headerBlockPresent = new Integer(0);
    SOAPHeaderBlock headerBlock;


    public void revoke(MessageContext msgContext) {

    }

    public InvocationResponse invoke(MessageContext msgContext) throws AxisFault {
        SOAPEnvelope envelope = msgContext.getEnvelope();
        if (envelope.getHeader() != null) {
            Iterator headerBlocks = envelope.getHeader().examineAllHeaderBlocks();
            SOAPFactory factory = OMAbstractFactory.getSOAP12Factory();
            SOAPHeader headerAdd = factory.createSOAPHeader(envelope);

            while (headerBlocks.hasNext()) {
                try {
                    headerBlock = (SOAPHeaderBlock) headerBlocks.next();
                } catch (ClassCastException e) {
                    continue;
                }
                Iterator attributes = headerBlock.getAllAttributes();

                if (attributes.hasNext()) {
                    OMAttribute firstAttribute = (OMAttribute) attributes.next();
                    attributeNS = firstAttribute.getNamespace();
                    attributePresent = true;
                }

                String roleValue = headerBlock.getRole();
                boolean mustUnderstand = headerBlock.getMustUnderstand();
                String elementName = headerBlock.getLocalName();
                OMNamespace headerBlockNamespace = headerBlock.getNamespace();

                if (elementName.equals(REQUEST_HEADERBLOCK_NAME)) {
                    if (roleValue == null || roleValue.equals(SAMPLE_ROLE + "/" + ROLE_BY_C) || roleValue.equals(SOAP12_ROLE + "/" + ULTIMATERECEIVER_ROLE) ||
                            roleValue.equals(SOAP12_ROLE + "/" + NEXT_ROLE)) {
                        headerBlock.setLocalName(RESPONSE_HEADERBLOCK_NAME);
                        if (attributePresent) {
                            headerBlock.removeAttribute((OMAttribute) headerBlock.getAllAttributes().next());
                            attributePresent = false;
                        }
                        headerBlockPresent = new Integer(1);
                        msgContext.getOperationContext().setProperty("HEADER_BLOCK_PRESENT", headerBlockPresent);
                        headerAdd.addChild(headerBlock);
                        msgContext.getOperationContext().setProperty("HEADER_BLOCK", headerAdd);

                    }
                } else {
                    if (roleValue == null || roleValue.equals(SAMPLE_ROLE + "/" + ROLE_BY_C) ||
                            roleValue.equals(SOAP12_ROLE + "/" + ULTIMATERECEIVER_ROLE) || roleValue.equals(SOAP12_ROLE + "/" + NEXT_ROLE)) {

                        if (mustUnderstand) {

                            SOAPBody body = factory.getDefaultEnvelope().getBody();
                            if (attributePresent && attributeNS.getName() == "http://schemas.xmlsoap.org/soap/envelope/") {

                            } else {

                                try {
                                    SOAPFault fault = factory.createSOAPFault(body);
                                    SOAPFaultCode code = factory.createSOAPFaultCode(fault);
                                    SOAPFaultValue value = factory.createSOAPFaultValue(code);
                                    value.setText("env:MustUnderstand");
                                    SOAPFaultReason reason = factory.createSOAPFaultReason(fault);
                                    SOAPFaultText text = factory.createSOAPFaultText(reason);
                                    text.setLang("en-US");
                                    text.setText("Header not understood");
                                    reason.addSOAPText(text);
                                    //fault.setReason(reason);
                                    if (roleValue != null && roleValue.equals(SAMPLE_ROLE + "/" + ROLE_BY_B)) {
                                        SOAPFaultNode node = factory.createSOAPFaultNode(fault);
                                        node.setNodeValue(SAMPLE_ROLE + "/" + ROLE_BY_B);
                                        SOAPFaultRole role = factory.createSOAPFaultRole(fault);
                                        role.setRoleValue(SAMPLE_ROLE + "/" + ROLE_BY_B);
                                        msgContext.setProperty(SOAP12Constants.SOAP_FAULT_NODE_LOCAL_NAME, node);
                                        msgContext.setProperty(SOAP12Constants.SOAP_FAULT_ROLE_LOCAL_NAME, role);
                                    }

                                    msgContext.setProperty(SOAP12Constants.SOAP_FAULT_CODE_LOCAL_NAME, code);
                                    msgContext.setProperty(SOAP12Constants.SOAP_FAULT_REASON_LOCAL_NAME, reason);

                                } catch (SOAPProcessingException e) {
                                    //e.printStackTrace();
                                }


                                headerBlock.discard();
                                SOAPHeaderBlock newHeaderBlock = null;
                                try {
                                    newHeaderBlock = envelope.getHeader().addHeaderBlock("NotUnderstood", envelope.getNamespace());
                                    newHeaderBlock.declareNamespace(headerBlockNamespace);
                                    newHeaderBlock.addAttribute("qname", headerBlockNamespace.getName() + ":" + elementName, null);
                                } catch (SOAPProcessingException e) {
                                    //e.printStackTrace();
                                }
                                headerBlockPresent = new Integer(1);
                                msgContext.getOperationContext().setProperty("HEADER_BLOCK_PRESENT", headerBlockPresent);
                                headerAdd.addChild(newHeaderBlock);
                                msgContext.getOperationContext().setProperty("HEADER_BLOCK", headerAdd);
                                throw new AxisFault("Intentional Failure from SOAP 1.2 testing ...");
                            }
                        }

                    }
                }
            }
            if (headerBlockPresent.equals(new Integer(0))) {
                msgContext.getOperationContext().setProperty("HEADER_BLOCK_PRESENT", headerBlockPresent);
            }

            headerBlockPresent = new Integer(0);

        } else {
            headerBlockPresent = new Integer(0);
            msgContext.getOperationContext().setProperty("HEADER_BLOCK_PRESENT", headerBlockPresent);
        }
        return InvocationResponse.CONTINUE;
    }
}
