/*
 * 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;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAPFault;
import org.apache.axiom.soap.SOAPFaultCode;
import org.apache.axiom.soap.SOAPFaultDetail;
import org.apache.axiom.soap.SOAPFaultNode;
import org.apache.axiom.soap.SOAPFaultReason;
import org.apache.axiom.soap.SOAPFaultRole;
import org.apache.axiom.soap.SOAPFaultSubCode;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.apache.axis2.context.MessageContext;

import javax.xml.namespace.QName;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * An exception which maps cleanly to a SOAP fault.
 * This is a base class for exceptions which are mapped to faults.
 *
 * @see <a href="http://www.w3.org/TR/2003/REC-soap12-part1-20030624/#soapfault">
 *      SOAP1.2 specification</a>
 * @see <a href="http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383507">SOAP1.1 Faults</a>
 *      <p/>
 *      SOAP faults contain
 *      <ol>
 *      <li>A fault string
 *      <li>A fault code
 *      <li>A fault actor
 *      <li>Fault details; an xml tree of fault specific elements
 *      </ol>
 *      <p/>
 *      As SOAP1.2 faults are a superset of SOAP1.1 faults, this type holds soap1.2 fault information. When
 *      a SOAP1.1 fault is created, spurious information can be discarded.
 *      Mapping
 *      <pre>
 *                                                             SOAP1.2              SOAP1.1
 *                                                             node                 faultactor
 *                                                             reason(0).text       faultstring
 *                                                             faultcode.value      faultcode
 *                                                             faultcode.subcode    (discarded)
 *                                                             detail               detail
 *                                                             role                 (discarded)
 *                                                             </pre>
 */


public class AxisFault extends RemoteException {
    private static final long serialVersionUID = -374933082062124907L;

    /**
     * assume headers are not used very often
     */
    private List<SOAPHeaderBlock> headers = new ArrayList<SOAPHeaderBlock>(0);

    private String message;

    private List<FaultReason> faultReasonList = new ArrayList<FaultReason>(1);
    private QName faultCode;
    private List<QName> faultSubCodes;
    private String faultNode;
    private String faultRole;
    private List<OMElement> details;

    private SOAPFaultCode soapFaultCode;
    private SOAPFaultReason soapFaultReason;
    private SOAPFaultNode soapFaultNode;
    private SOAPFaultRole soapFaultRole;
    private SOAPFaultDetail soapFaultDetail;

    /**
     * If not null, this MessageContext represents the fault as it
     * should be returned.  This is used by higher-level layers
     * that want to generate the message themselves so that
     * processing may take place before they return control (e.g. JAX-WS.)
     */
    private MessageContext faultMessageContext;

    /**
     * SOAP1.2: URI of faulting node. Null for unknown.
     * <p/>
     * The value of the Node element information item is the URI that
     * identifies the SOAP node that generated the fault.
     * SOAP nodes that do not act as the ultimate SOAP receiver MUST include this element
     * information item.
     * An ultimate SOAP receiver MAY include this element information item to
     * indicate explicitly that it generated the fault.
     */
    private String nodeURI;

	private String faultAction;


    /**
     * Constructor.
     *
     * @param message the human-readable text describing the fault
     */
    public AxisFault(String message) {
        this.message = message;
        addReason(message);
    }

    /**
     * Constructor
     *
     * @param faultCode   - fault code of the message as a QName
     * @param faultReason - the reason for the fault. The language will be defaulted to 'en'
     * @param cause embedded fault which caused this one
     */
    public AxisFault(QName faultCode, String faultReason, Throwable cause) {
        this(faultReason, cause);
        setFaultCode(faultCode);
    }
    
    /**
     * Constructor
     *
     * @param faultCode       - fault code of the message as a QName
     * @param faultSubCodes   - list sub fault codes as a list if QNames
     * @param faultReason - the reason for the fault. The language will be defaulted to 'en'
     * @param cause embedded fault which caused this one
     */
    public AxisFault(QName faultCode, List<QName> faultSubCodes, String faultReason, Throwable cause) {
        this(faultReason, cause);
        setFaultCode(faultCode);
        setFaultSubCodes(faultSubCodes);
    }

    /**
     * Constructor
     *
     * @param faultCode a QName for the fault code
     * @param faultReason the reason for the fault. The language will be defaulted to 'en'
     * @param faultNode a URL identifying the SOAP node generating this fault, or null
     * @param faultRole a URL identifying the SOAP role active when generating this fault, or null
     * @param faultDetail arbitrary XML containing application-specific fault data
     */
    public AxisFault(QName faultCode, String faultReason, String faultNode, String faultRole,
                     OMElement faultDetail) {
        this(faultReason, faultCode);
        this.faultNode = faultNode;
        this.faultRole = faultRole;
        setDetail(faultDetail);
    }

    /**
     * This is just a convenience method for the user. If you set these, do not use other methods
     * in this class to get and set things.
     * Any of the parameters can be null
     *
     * @param soapFaultCode the fault code
     * @param soapFaultReason the fault reason
     * @param soapFaultNode the SOAPFaultNode representing the source node for this fault
     * @param soapFaultRole the SOAPFaultRole representing the source role for this fault
     * @param soapFaultDetail the SOAPFaultDetail containing any application-specific info
     */
    public AxisFault(SOAPFaultCode soapFaultCode, SOAPFaultReason soapFaultReason,
                     SOAPFaultNode soapFaultNode, SOAPFaultRole soapFaultRole,
                     SOAPFaultDetail soapFaultDetail) {
        initializeValues(soapFaultCode, soapFaultReason, soapFaultNode, soapFaultRole,
                         soapFaultDetail);
    }

    public AxisFault(SOAPFault fault) {
        initializeValues(fault);
    }

    public AxisFault(SOAPFault fault, MessageContext faultCtx) {
        initializeValues(fault);
        faultMessageContext = faultCtx;
    }

    private void initializeValues(SOAPFault fault) {
        if (fault != null) {
            initializeValues(fault.getCode(), fault.getReason(), fault.getNode(),
                             fault.getRole(), fault.getDetail());
        }
    }

    private void initializeValues(SOAPFaultCode soapFaultCode,
                                  SOAPFaultReason soapFaultReason,
                                  SOAPFaultNode soapFaultNode,
                                  SOAPFaultRole soapFaultRole,
                                  SOAPFaultDetail soapFaultDetail) {
        this.soapFaultCode = soapFaultCode;
        this.soapFaultReason = soapFaultReason;
        this.soapFaultNode = soapFaultNode;
        this.soapFaultRole = soapFaultRole;
        this.soapFaultDetail = soapFaultDetail;

        if (soapFaultDetail != null) {
//            OMElement exceptionElement = soapFaultDetail.getFirstChildWithName(
//                    new QName(SOAPConstants.SOAP_FAULT_DETAIL_EXCEPTION_ENTRY));
//            if (exceptionElement != null && exceptionElement.getText() != null) {
//                cause = new Exception(exceptionElement.getText());
//            }

            details = new ArrayList<OMElement>();
            for (Iterator<?> it = soapFaultDetail.getChildElements(); it.hasNext(); ) {
                details.add((OMElement)it.next());
            }
        }

        if (soapFaultReason != null) {
            message = soapFaultReason.getText();
        }

        if (soapFaultCode != null) {
            // This works the same regardless of SOAP version
            faultCode = soapFaultCode.getTextAsQName();

            SOAPFaultSubCode subCode = soapFaultCode.getSubCode();
            if (subCode != null) {
                faultSubCodes = new ArrayList<QName>();
                while (subCode != null) {
                    faultSubCodes.add(subCode.getValue().getTextAsQName());
                    subCode = subCode.getSubCode();
                }
            }
        }
    }

    /**
     * Construct a fault from a Throwable.  This is a protected constructor - in general
     * to make an AxisFault from an Exception, you should be calling AxisFault.makeFault(e),
     * which prevents AxisFaults within AxisFaults.
     *
     * @param cause the Throwable that caused the problem
     */
    protected AxisFault(Throwable cause) {
        this((cause != null)
                ? cause.getMessage()
                : null, cause);
    }

    /**
     * Constructor.
     *
     * @param messageText - this will appear as the Text in the Reason information item of SOAP Fault
     * @param faultCode   - this will appear as the Value in the Code information item of SOAP Fault
     */
    public AxisFault(String messageText, String faultCode) {
        this(messageText);
        setFaultCode(faultCode);
    }

    /**
     * Constructor
     *
     * @param messageText this will appear as the Text in the Reason information item of SOAP Fault
     * @param faultCode this will appear as the Value in the Code information item of SOAP Fault
     */
    public AxisFault(String messageText, QName faultCode) {
        this(messageText);
        setFaultCode(faultCode);
    }

    /**
     * Constructor
     *
     * @param message this will appear as the Text in the Reason information item of SOAP Fault
     * @param cause the embedded Throwable that caused this fault
     */
    public AxisFault(String message, Throwable cause) {
        super(message, cause);

        if (message != null) {
            addReason(message);
            this.message = message;
        }
    }

    /**
     * @param messageText - this will appear as the Text in the Reason information item of SOAP Fault
     * @param faultCode   - this will appear as the Value in the Code information item of SOAP Fault
     * @param cause       - this will appear under the Detail information item of SOAP Fault
     */
    public AxisFault(String messageText, QName faultCode, Throwable cause) {
        this(messageText, cause);
        setFaultCode(faultCode);
    }

    
    /**
     * @param message
     * @param faultMessageContext
     * @param cause
     */
    public AxisFault(String message, MessageContext faultMessageContext, Throwable cause) {
        super(message, cause);

        this.faultMessageContext = faultMessageContext;
    }


    /**
     * @param messageText - this will appear as the Text in the Reason information item of SOAP Fault
     * @param faultCode   - this will appear as the Value in the Code information item of SOAP Fault
     * @param cause       - this will appear under the Detail information item of SOAP Fault
     */
    public AxisFault(String messageText, String faultCode, Throwable cause) {
        this(messageText, cause);
        setFaultCode(faultCode);
    }

    /**
     * Create an AxisFault by providing a textual message and a MessageContext
     * that contains the actual fault representation.
     *
     * @param message             A string that's really only useful for logging.
     * @param faultMessageContext A MessageContext which must contain SOAP fault info
     */
    public AxisFault(String message, MessageContext faultMessageContext) {
        this(message);
        this.faultMessageContext = faultMessageContext;
    }

    /**
     * Add a header to the list of fault headers
     *
     * @param header to add.
     */
    public void addHeader(SOAPHeaderBlock header) {
        headers.add(header);
    }

    /**
     * Add a reason for the fault in the empty "" language
     *
     * @param text text message
     */
    public void addReason(String text) {
        faultReasonList.add(new FaultReason(text, ""));
    }

    /**
     * Add a reason for the fault
     *
     * @param text     text message
     * @param language language
     */
    public void addReason(String text, String language) {
        faultReasonList.add(new FaultReason(text, language));
    }

    /**
     * Returns the first fault reason, if available. If not found, returns null.
     *
     * @return faultReason
     */
    public String getReason() {
        if (faultReasonList.size() >= 1) {
            return faultReasonList.get(0).getText();
        } else if (soapFaultReason != null) {
            return soapFaultReason.getText();
        }

        return null;
    }

    /**
     * Iterate over all of the headers
     *
     * @return iterator
     */
    public ListIterator<SOAPHeaderBlock> headerIterator() {
        return headers.listIterator();
    }

    /**
     * Get at the headers. Useful for java1.5 iteration.
     *
     * @return the headers for this fault
     */
    public List<SOAPHeaderBlock> headers() {
        return headers;
    }

    /**
     * Make an AxisFault based on a passed Exception.  If the Exception is
     * already an AxisFault, simply use that.  Otherwise, wrap it in an
     * AxisFault.  If the Exception is an InvocationTargetException (which
     * already wraps another Exception), get the wrapped Exception out from
     * there and use that instead of the passed one.
     *
     * @param e the <code>Exception</code> to build a fault for
     * @return an <code>AxisFault</code> representing <code>e</code>
     */
    public static AxisFault makeFault(Throwable e) {
        if (e instanceof InvocationTargetException) {
            return makeFault(((InvocationTargetException) e).getTargetException());
        } else if (e instanceof UndeclaredThrowableException) {
            Throwable t = ((UndeclaredThrowableException) e).getCause();
            if (t instanceof Exception) {
                e = t;
            }
        }
        if (e instanceof AxisFault) {
            return (AxisFault) e;
        }

        return new AxisFault(e);
    }

    /**
     * Get the current fault detail. If the fault has several detail elements, only the first one is
     * returned.
     * 
     * @return the (first) detail element, or <code>null</code> if there is no detail element
     */
    public OMElement getDetail() {
        return details == null || details.isEmpty() ? null : details.get(0);
    }

    /**
     * Get the SOAP fault detail elements.
     * 
     * @return the list of SOAP fault detail elements, or <code>null</code> if no detail elements
     *         have been set for this fault
     */
    public List<OMElement> getDetails() {
        return details;
    }

    public QName getFaultCode() {
        return faultCode;
    }

    public List<QName> getFaultSubCodes() {
        return faultSubCodes;
    }

    /**
     * @return SOAPFaultCode if, user has set a {@link SOAPFaultCode} element when constructing the
     *         {@link #AxisFault(org.apache.axiom.soap.SOAPFaultCode, org.apache.axiom.soap.SOAPFaultReason, org.apache.axiom.soap.SOAPFaultNode, org.apache.axiom.soap.SOAPFaultRole, org.apache.axiom.soap.SOAPFaultDetail) AxisFault}
     */
    public SOAPFaultCode getFaultCodeElement() {
        return soapFaultCode;
    }

    /**
     * @return SOAPFaultCode if, user has set a {@link SOAPFaultReason} element when constructing the
     *         {@link #AxisFault(org.apache.axiom.soap.SOAPFaultCode, org.apache.axiom.soap.SOAPFaultReason, org.apache.axiom.soap.SOAPFaultNode, org.apache.axiom.soap.SOAPFaultRole, org.apache.axiom.soap.SOAPFaultDetail) AxisFault}
     */
    public SOAPFaultReason getFaultReasonElement() {
        return soapFaultReason;
    }

    /**
     * @return SOAPFaultCode if, user has set a {@link SOAPFaultNode} element when constructing the
     *         {@link #AxisFault(org.apache.axiom.soap.SOAPFaultCode, org.apache.axiom.soap.SOAPFaultReason, org.apache.axiom.soap.SOAPFaultNode, org.apache.axiom.soap.SOAPFaultRole, org.apache.axiom.soap.SOAPFaultDetail) AxisFault}
     */
    public SOAPFaultNode getFaultNodeElement() {
        return soapFaultNode;
    }

    /**
     * @return SOAPFaultCode if, user has set a {@link SOAPFaultRole} element when constructing the
     *         {@link #AxisFault(org.apache.axiom.soap.SOAPFaultCode, org.apache.axiom.soap.SOAPFaultReason, org.apache.axiom.soap.SOAPFaultNode, org.apache.axiom.soap.SOAPFaultRole, org.apache.axiom.soap.SOAPFaultDetail) AxisFault}
     */
    public SOAPFaultRole getFaultRoleElement() {
        return soapFaultRole;
    }

    /**
     * @return SOAPFaultCode if, user has set a {@link SOAPFaultDetail} element when constructing the
     *         {@link #AxisFault(org.apache.axiom.soap.SOAPFaultCode, org.apache.axiom.soap.SOAPFaultReason, org.apache.axiom.soap.SOAPFaultNode, org.apache.axiom.soap.SOAPFaultRole, org.apache.axiom.soap.SOAPFaultDetail) AxisFault}
     */
    public SOAPFaultDetail getFaultDetailElement() {
        return soapFaultDetail;
    }

    /**
     * Get the faulting node uri.
     * SOAP1.2
     *
     * @return URI as a string or null
     */
    public String getNodeURI() {
        return nodeURI;
    }

    /**
     * Set the entire detail element of the fault
     *
     * @param detail an OMElement which MUST be 
     */
    public void setDetail(OMElement detail) {
        details = new ArrayList<OMElement>();
        details.add(detail);
    }

    /**
     * Set the SOAP fault details.
     * 
     * @param details
     *            a list of elements for the SOAP fault details
     */
    public void setDetails(List<OMElement> details) {
        this.details = details;
    }

    public void setFaultCode(QName soapFaultCode) {
        this.faultCode = soapFaultCode;
    }
    
    public void setFaultSubCodes(List<QName> faultSubCodes) {
        this.faultSubCodes = faultSubCodes;
    }
    
    public void setFaultCode(String soapFaultCode) {
        // TODO: is it really safe to assume that the passed string is always the localpart?
        // What if someone passes soapenv:Sender?
        faultCode = new QName(soapFaultCode);
    }

    /**
     * Set the faulting node uri. (SOAP1.2)
     *
     * @param nodeURI a String containing a URI indicating which SOAP Node faulted
     */
    public void setNodeURI(String nodeURI) {
        this.nodeURI = nodeURI;
    }

    public String getFaultNode() {
        return faultNode;
    }

    public String getFaultRole() {
        return faultRole;
    }

    /**
     * Returns the MessageContext representation of the fault if the fault
     * was created by providing that.
     *
     * @return The MessageContext representing the fault message or null if the
     *         fault was not created with MessageContext representation.
     */
    public MessageContext getFaultMessageContext() {
        return faultMessageContext;
    }

    class FaultReason implements Serializable{
        
        private static final long serialVersionUID = -8125991422614607169L;

        /**
         * Language of the reason.
         * xml:lang="en" "en-GB" or just ""
         */
        private String language = "";

        /**
         * env:reasontext
         */
        private String text;

        public FaultReason() {
        }

        public FaultReason(String text, String language) {
            this.text = text;
            this.language = language;
        }

        /**
         * Returns a string representation of the object.
         *
         * @return the text value
         */
        public String toString() {
            return text;
        }

        public String getLanguage() {
            return language;
        }

        public String getText() {
            return text;
        }

        public void setLanguage(String language) {
            this.language = language;
        }

        public void setText(String text) {
            this.text = text;
        }
    }
    
    /**
     * @return the action value set for the fault message  
     */
	public String getFaultAction() {
		return faultAction;
	}

	/**
	 * Set the (OPTIONAL) action value for the fault message
     *
	 * @param faultAction a String containing an action URI for the fault
	 */
	public void setFaultAction(String faultAction) {
		this.faultAction = faultAction;
	}

    /**
     * Returns the detail message, including the message from the cause, if any, of this exception.
     *
     * @return the detail message
     */
    public String getMessage() {
        return message;
    }

    /**
     * this field is used to identify the axis2 fault type
     */
    private int faultType;

    public int getFaultType() {
        return faultType;
    }

    public void setFaultType(int faultType) {
        this.faultType = faultType;
    }
}
