/*
 * 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.axiom.soap.impl.builder;


import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.OMNodeEx;
import org.apache.axiom.om.impl.exception.OMBuilderException;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPFault;
import org.apache.axiom.soap.SOAPFaultCode;
import org.apache.axiom.soap.SOAPFaultReason;
import org.apache.axiom.soap.SOAPFaultSubCode;
import org.apache.axiom.soap.SOAPProcessingException;

import javax.xml.stream.XMLStreamReader;
import java.util.Vector;

public class SOAP12BuilderHelper extends SOAPBuilderHelper {

    private SOAPFactory factory;
    private boolean codePresent = false;
    private boolean reasonPresent = false;
    private boolean nodePresent = false;
    private boolean rolePresent = false;
    private boolean detailPresent = false;
    private boolean subcodeValuePresent = false;
    private boolean subSubcodePresent = false;
    private boolean valuePresent = false;
    private boolean subcodePresent = false;
    private boolean codeprocessing = false;
    private boolean subCodeProcessing = false;
    private boolean reasonProcessing = false;
    private Vector detailElementNames;

    public SOAP12BuilderHelper(StAXSOAPModelBuilder builder) {
        super(builder);
        factory = builder.getSoapFactory();
    }

    public OMElement handleEvent(XMLStreamReader parser,
                                 OMElement parent,
                                 int elementLevel) throws SOAPProcessingException {

        this.parser = parser;
        OMElement element = null;

        if (elementLevel == 4) {
            if (parser.getLocalName().equals(
                    SOAP12Constants.SOAP_FAULT_CODE_LOCAL_NAME)) {
                if (codePresent) {
                    throw new OMBuilderException(
                            "Multiple Code element encountered");
                } else {
                    element =
                            factory.createSOAPFaultCode((SOAPFault) parent,
                                    builder);
                    codePresent = true;
                    codeprocessing = true;
                }
            } else if (parser.getLocalName().equals(
                    SOAP12Constants.SOAP_FAULT_REASON_LOCAL_NAME)) {
                if (!codeprocessing && !subCodeProcessing) {
                    if (codePresent) {
                        if (reasonPresent) {
                            throw new OMBuilderException(
                                    "Multiple Reason Element encountered");
                        } else {
                            element =
                                    factory.createSOAPFaultReason(
                                            (SOAPFault) parent, builder);
                            reasonPresent = true;
                            reasonProcessing = true;
                        }
                    } else {
                        throw new OMBuilderException(
                                "Wrong element order encountred at " +
                                parser.getLocalName());
                    }
                } else {
                    if (codeprocessing) {
                        throw new OMBuilderException(
                                "Code doesn't have a value");
                    } else {
                        throw new OMBuilderException(
                                "A subcode doesn't have a Value");
                    }
                }

            } else if (parser.getLocalName().equals(
                    SOAP12Constants.SOAP_FAULT_NODE_LOCAL_NAME)) {
                if (!reasonProcessing) {
                    if (reasonPresent && !rolePresent && !detailPresent) {
                        if (nodePresent) {
                            throw new OMBuilderException(
                                    "Multiple Node element encountered");
                        } else {
                            element =
                                    factory.createSOAPFaultNode(
                                            (SOAPFault) parent, builder);
                            nodePresent = true;
                        }
                    } else {
                        throw new OMBuilderException(
                                "wrong element order encountered at " +
                                parser.getLocalName());
                    }
                } else {
                    throw new OMBuilderException(
                            "Reason element Should have a text");
                }
            } else if (parser.getLocalName().equals(
                    SOAP12Constants.SOAP_FAULT_ROLE_LOCAL_NAME)) {
                if (!reasonProcessing) {
                    if (reasonPresent && !detailPresent) {
                        if (rolePresent) {
                            throw new OMBuilderException(
                                    "Multiple Role element encountered");
                        } else {
                            element =
                                    factory.createSOAPFaultRole(
                                            (SOAPFault) parent, builder);
                            rolePresent = true;
                        }
                    } else {
                        throw new OMBuilderException(
                                "Wrong element order encountered at " +
                                parser.getLocalName());
                    }
                } else {
                    throw new OMBuilderException(
                            "Reason element should have a text");
                }
            } else if (parser.getLocalName().equals(
                    SOAP12Constants.SOAP_FAULT_DETAIL_LOCAL_NAME)) {
                if (!reasonProcessing) {
                    if (reasonPresent) {
                        if (detailPresent) {
                            throw new OMBuilderException(
                                    "Multiple detail element encountered");
                        } else {
                            element =
                                    factory.createSOAPFaultDetail(
                                            (SOAPFault) parent, builder);
                            detailPresent = true;
                        }
                    } else {
                        throw new OMBuilderException(
                                "wrong element order encountered at " +
                                parser.getLocalName());
                    }
                } else {
                    throw new OMBuilderException(
                            "Reason element should have a text");
                }
            } else {
                throw new OMBuilderException(
                        parser.getLocalName() +
                        " unsupported element in SOAPFault element");
            }

        } else if (elementLevel == 5) {
            if (parent.getLocalName().equals(
                    SOAP12Constants.SOAP_FAULT_CODE_LOCAL_NAME)) {
                if (parser.getLocalName().equals(
                        SOAP12Constants.SOAP_FAULT_VALUE_LOCAL_NAME)) {
                    if (!valuePresent) {
                        element =
                                factory.createSOAPFaultValue(
                                        (SOAPFaultCode) parent, builder);
                        valuePresent = true;
                        codeprocessing = false;
                    } else {
                        throw new OMBuilderException(
                                "Multiple value Encountered in code element");
                    }

                } else if (parser.getLocalName().equals(
                        SOAP12Constants.SOAP_FAULT_SUB_CODE_LOCAL_NAME)) {
                    if (!subcodePresent) {
                        if (valuePresent) {
                            element =
                                    factory.createSOAPFaultSubCode(
                                            (SOAPFaultCode) parent, builder);
                            subcodePresent = true;
                            subCodeProcessing = true;
                        } else {
                            throw new OMBuilderException(
                                    "Value should present before the subcode");
                        }

                    } else {
                        throw new OMBuilderException(
                                "multiple subcode Encountered in code element");
                    }
                } else {
                    throw new OMBuilderException(
                            parser.getLocalName() +
                            " is not supported inside the code element");
                }

            } else if (parent.getLocalName().equals(
                    SOAP12Constants.SOAP_FAULT_REASON_LOCAL_NAME)) {
                if (parser.getLocalName().equals(
                        SOAP12Constants.SOAP_FAULT_TEXT_LOCAL_NAME)) {
                    element =
                            factory.createSOAPFaultText(
                                    (SOAPFaultReason) parent, builder);
                    ((OMNodeEx)element).setComplete(false);
                    reasonProcessing = false;
                } else {
                    throw new OMBuilderException(
                            parser.getLocalName() +
                            " is not supported inside the reason");
                }
            } else if (parent.getLocalName().equals(
                    SOAP12Constants.SOAP_FAULT_DETAIL_LOCAL_NAME)) {
                element =
                        this.factory.createOMElement(
                                parser.getLocalName(), null, parent, builder);
                builder.setProcessingDetailElements(true);
                detailElementNames = new Vector();
                detailElementNames.add(parser.getLocalName());

            } else {
                throw new OMBuilderException(
                        parent.getLocalName() +
                        " should not have child element");
            }


        } else if (elementLevel > 5) {
            if (parent.getLocalName().equals(
                    SOAP12Constants.SOAP_FAULT_SUB_CODE_LOCAL_NAME)) {
                if (parser.getLocalName().equals(
                        SOAP12Constants.SOAP_FAULT_VALUE_LOCAL_NAME)) {
                    if (subcodeValuePresent) {
                        throw new OMBuilderException(
                                "multiple subCode value encountered");
                    } else {
                        element =
                                factory.createSOAPFaultValue(
                                        (SOAPFaultSubCode) parent, builder);
                        subcodeValuePresent = true;
                        subSubcodePresent = false;
                        subCodeProcessing = false;
                    }
                } else if (parser.getLocalName().equals(
                        SOAP12Constants.SOAP_FAULT_SUB_CODE_LOCAL_NAME)) {
                    if (subcodeValuePresent) {
                        if (!subSubcodePresent) {
                            element =
                                    factory.createSOAPFaultSubCode(
                                            (SOAPFaultSubCode) parent,
                                            builder);
                            subcodeValuePresent = false;
                            subSubcodePresent = true;
                            subCodeProcessing = true;
                        } else {
                            throw new OMBuilderException(
                                    "multiple subcode encountered");
                        }
                    } else {
                        throw new OMBuilderException(
                                "Value should present before the subcode");
                    }
                } else {
                    throw new OMBuilderException(
                            parser.getLocalName() +
                            " is not supported inside the subCode element");
                }
            } else if (builder.isProcessingDetailElements()) {
                int detailElementLevel = 0;
                boolean localNameExist = false;
                for (int i = 0; i < detailElementNames.size(); i++) {
                    if (parent.getLocalName().equals(
                            detailElementNames.get(i))) {
                        localNameExist = true;
                        detailElementLevel = i + 1;
                    }
                }
                if (localNameExist) {
                    detailElementNames.setSize(detailElementLevel);
                    element =
                            this.factory.createOMElement(
                                    parser.getLocalName(),
                                    null,
                                    parent,
                                    builder);
                    detailElementNames.add(parser.getLocalName());
                }

            } else {
                throw new OMBuilderException(
                        parent.getLocalName() +
                        " should not have child at element level " +
                        elementLevel);
            }
        }

        processNamespaceData(element, false);
        processAttributes(element);
        return element;
    }
}