/*
 * 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;
import java.util.Locale;

/**
 * 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.getFaultReasonText(Locale.ENGLISH);
        }

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

            SOAPFaultSubCode subCode = soapFaultCode.getSubCode();
            if (subCode != null) {
                faultSubCodes = new ArrayList<QName>();
                while (subCode != null) {
                    faultSubCodes.add(subCode.getValueAsQName());
                    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.getFaultReasonText(Locale.ENGLISH);
        }

        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;
    }
}
