package be.iminds.ilabt.jfed.lowlevel;

/**
 * GeniException
 */
public class JFedException extends Exception {
    private final XMLRPCCallDetails xmlRpcResult;
    private final GeniResponseCode geniResponseCode;
    private final XmlRpcApiCallReply reply;

    /**
     * @param geniResponseCode may be null
     */
    public JFedException(String s, Throwable ex, XMLRPCCallDetails xmlRpcResult, GeniResponseCode geniResponseCode) {
        super(s, ex);
        this.xmlRpcResult = xmlRpcResult;
        this.geniResponseCode = geniResponseCode;
        this.reply = null;
    }

    public JFedException(String s, Throwable ex, XMLRPCCallDetails xmlRpcResult) {
        super(s, ex);
        this.xmlRpcResult = xmlRpcResult;
        this.geniResponseCode = null;
        this.reply = null;
    }

    public JFedException(String s, JFedException ex) {
        super(s, ex);
        this.xmlRpcResult = ex.getXmlRpcResult();
        this.geniResponseCode = ex.getGeniResponseCode();
        this.reply = ex.reply;
    }

    public JFedException(String s, Throwable ex) {
        super(s, ex);
        this.xmlRpcResult = null;
        this.geniResponseCode = null;
        this.reply = null;
    }

    /**
     * @param geniResponseCode may be null
     */
    public JFedException(String s, XMLRPCCallDetails xmlRpcResult, GeniResponseCode geniResponseCode) {
        super(s);
        this.xmlRpcResult = xmlRpcResult;
        this.geniResponseCode = geniResponseCode;
        this.reply = null;
    }

    public JFedException(String s) {
        super(s);
        this.xmlRpcResult = null;
        this.geniResponseCode = null;
        this.reply = null;
    }

    /* Sometimes, a full reply is known */
    public JFedException(String s, XmlRpcApiCallReply reply) {
        super(s);
        this.xmlRpcResult = reply.getXMLRPCCallDetails();
        this.geniResponseCode = reply.getGeniResponseCode();
        this.reply = reply;
    }

    public XMLRPCCallDetails getXmlRpcResult() {
        return xmlRpcResult;
    }

    public AbstractApi.XMLRPCCallDetailsWithCodeValueError getXmlRpcResultWithCodeValueError() {
        if (xmlRpcResult == null)
            return null;
        if (xmlRpcResult instanceof AbstractApi.XMLRPCCallDetailsWithCodeValueError)
            return (AbstractApi.XMLRPCCallDetailsWithCodeValueError) xmlRpcResult;
        return null;
    }

    public GeniResponseCode getGeniResponseCode() {
        return geniResponseCode;
    }

    public XmlRpcApiCallReply getXmlRpcReply() {
        return reply;
    }

    public SfaApiCallReply getSfaReply() {
        if (reply == null || !(reply instanceof SfaApiCallReply))
            return null;
        return (SfaApiCallReply) reply;
    }

    @Override
    public String toString() {
        if (xmlRpcResult != null)
            return super.toString() + " GeniException.XmlRpcResult=" + xmlRpcResult + '}';
        else
            return super.toString();
    }

    @Override
    public String getMessage() {
        String message = super.getMessage();

        if (reply != null) {
            message += "[code=" + reply.getGeniResponseCode() + ", output='" + reply.getOutput() + "]";
        }

        return message;
    }
}
