/*
 * 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.ode.bpel.elang.xquery10.runtime;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.transform.TransformerFactory;
import javax.xml.xpath.XPathConstants;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQConstants;
import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQItem;
import javax.xml.xquery.XQItemType;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQResultSequence;
import javax.xml.xquery.XQSequence;
import javax.xml.xquery.XQSequenceType;
import javax.xml.xquery.XQStaticContext;

import net.sf.saxon.Configuration;
import net.sf.saxon.om.Item;
import net.sf.saxon.om.Validation;
import net.sf.saxon.trans.DynamicError;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.value.DurationValue;
import net.sf.saxon.value.Value;
import net.sf.saxon.xqj.SaxonXQConnection;
import net.sf.saxon.xqj.SaxonXQDataSource;
import net.sf.saxon.xqj.SaxonXQItem;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ode.bpel.common.FaultException;
import org.apache.ode.bpel.elang.xpath20.compiler.Constants;
import org.apache.ode.bpel.elang.xpath20.compiler.WrappedResolverException;
import org.apache.ode.bpel.elang.xpath20.runtime.JaxpFunctionResolver;
import org.apache.ode.bpel.elang.xpath20.runtime.JaxpVariableResolver;
import org.apache.ode.bpel.elang.xquery10.compiler.XQuery10BpelFunctions;
import org.apache.ode.bpel.elang.xquery10.obj.OXQuery10ExpressionBPEL20;
import org.apache.ode.bpel.explang.ConfigurationException;
import org.apache.ode.bpel.explang.EvaluationContext;
import org.apache.ode.bpel.explang.EvaluationException;
import org.apache.ode.bpel.explang.ExpressionLanguageRuntime;
import org.apache.ode.bpel.obj.OExpression;
import org.apache.ode.utils.DOMUtils;
import org.apache.ode.utils.ISO8601DateParser;
import org.apache.ode.utils.NSContext;
import org.apache.ode.utils.xsd.Duration;
import org.apache.ode.utils.xsl.XslTransformHandler;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;


/**
 * XQuery 1.0 Expression Language run-time subsytem. Saxon implementation.
 */
@SuppressWarnings("deprecation")
public class XQuery10ExpressionRuntime implements ExpressionLanguageRuntime {
    static final short NODE_TYPE = 1;
    static final short NODESET_TYPE = 2;
    static final short STRING_TYPE = 3;
    static final short BOOLEAN_TYPE = 4;
    static final short NUMBER_TYPE = 5;

    /** Class-level logger. */
    private static final Log __log = LogFactory.getLog(XQuery10ExpressionRuntime.class);

    /**
     * Creates a new XQuery10ExpressionRuntime object.
     */
    public XQuery10ExpressionRuntime() {
    }

    /**
     * Initialize XSL Transformer
     *
     * @param properties properties
     *
     * @throws ConfigurationException ConfigurationException
     */
    public void initialize(Map properties) throws ConfigurationException {
        TransformerFactory trsf = new net.sf.saxon.TransformerFactoryImpl();
        XslTransformHandler.getInstance().setTransformerFactory(trsf);
    }

    /**
     *
     * @see org.apache.ode.bpel.explang.ExpressionLanguageRuntime#evaluateAsString(org.apache.ode.bpel.obj.OExpression,
     *      org.apache.ode.bpel.explang.EvaluationContext)
     */
    public String evaluateAsString(OExpression cexp, EvaluationContext ctx)
        throws FaultException, EvaluationException {
        return (String) evaluate(cexp, ctx, XPathConstants.STRING);
    }

    /**
     *
     * @see org.apache.ode.bpel.explang.ExpressionLanguageRuntime#evaluateAsBoolean(org.apache.ode.bpel.obj.OExpression,
     *      org.apache.ode.bpel.explang.EvaluationContext)
     */
    public boolean evaluateAsBoolean(OExpression cexp, EvaluationContext ctx)
        throws FaultException, EvaluationException {
        return (Boolean) evaluate(cexp, ctx, XPathConstants.BOOLEAN);
    }

    /**
     * Evaluate expression and return a number
     *
     * @param cexp cexp
     * @param ctx ctx
     *
     * @return type
     *
     * @throws FaultException FaultException
     * @throws EvaluationException EvaluationException
     */
    public Number evaluateAsNumber(OExpression cexp, EvaluationContext ctx)
        throws FaultException, EvaluationException {
        return (Number) evaluate(cexp, ctx, XPathConstants.NUMBER);
    }

    /**
     *
     * @see org.apache.ode.bpel.explang.ExpressionLanguageRuntime#evaluate(org.apache.ode.bpel.obj.OExpression,
     *      org.apache.ode.bpel.explang.EvaluationContext)
     */
    public List evaluate(OExpression cexp, EvaluationContext ctx)
        throws FaultException, EvaluationException {
        List result;
        Object someRes = evaluate(cexp, ctx, XPathConstants.NODESET);

        if (someRes instanceof List) {
            result = (List) someRes;
            if (__log.isDebugEnabled()) {
                __log.debug("Returned list of size " + result.size());
            }

            if ((result.size() == 1) && !(result.get(0) instanceof Node)) {
                // Dealing with a Java class
                Object simpleType = result.get(0);

                // Dates get a separate treatment as we don't want to call toString on them
                String textVal;

                if (simpleType instanceof Date) {
                    textVal = ISO8601DateParser.format((Date) simpleType);
                } else if (simpleType instanceof DurationValue) {
                    textVal = ((DurationValue) simpleType).getStringValue();
                } else {
                    textVal = simpleType.toString();
                }

                // Wrapping in a document
                Document d = DOMUtils.newDocument();

                // Giving our node a parent just in case it's an LValue expression
                Element wrapper = d.createElement("wrapper");
                Text text = d.createTextNode(textVal);
                wrapper.appendChild(text);
                d.appendChild(wrapper);
                result = Collections.singletonList(text);
            }
        } else if (someRes instanceof NodeList) {
            NodeList retVal = (NodeList) someRes;
            if (__log.isDebugEnabled()) {
                __log.debug("Returned node list of size " + retVal.getLength());
            }
            result = new ArrayList(retVal.getLength());

            for (int m = 0; m < retVal.getLength(); ++m) {
                Node val = retVal.item(m);

                if (val.getNodeType() == Node.DOCUMENT_NODE) {
                    val = ((Document) val).getDocumentElement();
                }

                result.add(val);
            }
        } else {
            result = null;
        }

        return result;
    }

    /**
     * Evaluate expression and return a node
     *
     * @param cexp cexp
     * @param ctx ctx
     *
     * @return type
     *
     * @throws FaultException FaultException
     * @throws EvaluationException EvaluationException
     */
    public Node evaluateNode(OExpression cexp, EvaluationContext ctx)
        throws FaultException, EvaluationException {
        List retVal = evaluate(cexp, ctx);

        if (retVal.size() == 0) {
            throw new FaultException(cexp.getOwner().getConstants().getQnSelectionFailure(),
                "No results for expression: " + cexp);
        }

        if (retVal.size() > 1) {
            throw new FaultException(cexp.getOwner().getConstants().getQnSelectionFailure(),
                "Multiple results for expression: " + cexp);
        }

        return (Node) retVal.get(0);
    }

    /**
     * Evaluate expression and return a date
     *
     * @param cexp cexp
     * @param context context
     *
     * @return type
     *
     * @throws FaultException FaultException
     * @throws EvaluationException EvaluationException
     */
    public Calendar evaluateAsDate(OExpression cexp, EvaluationContext context)
        throws FaultException, EvaluationException {
        List literal = DOMUtils.toList(evaluate(cexp, context,
                    XPathConstants.NODESET));

        if (literal.size() == 0) {
            throw new FaultException(cexp.getOwner().getConstants().getQnSelectionFailure(),
                "No results for expression: " + cexp);
        }

        if (literal.size() > 1) {
            throw new FaultException(cexp.getOwner().getConstants().getQnSelectionFailure(),
                "Multiple results for expression: " + cexp);
        }

        Object date = literal.get(0);

        if (date instanceof Calendar) {
            return (Calendar) date;
        }

        if (date instanceof Date) {
            Calendar cal = Calendar.getInstance();
            cal.setTime((Date) date);

            return cal;
        }

        if (date instanceof Element) {
            date = ((Element) date).getTextContent();
        }

        try {
            return ISO8601DateParser.parseCal(date.toString());
        } catch (Exception ex) {
            String errmsg = "Invalid date: " + literal;
            __log.error(errmsg, ex);
            throw new FaultException(cexp.getOwner().getConstants().getQnInvalidExpressionValue(),
                errmsg);
        }
    }

    /**
     * Evaluate expression and return duration
     *
     * @param cexp cexp
     * @param context context
     *
     * @return type
     *
     * @throws FaultException FaultException
     * @throws EvaluationException EvaluationException
     */
    public Duration evaluateAsDuration(OExpression cexp,
        EvaluationContext context) throws FaultException, EvaluationException {
        String literal = this.evaluateAsString(cexp, context);

        try {
            return new Duration(literal);
        } catch (Exception ex) {
            String errmsg = "Invalid duration: " + literal;
            __log.error(errmsg, ex);
            throw new FaultException(cexp.getOwner().getConstants().getQnInvalidExpressionValue(),
                errmsg);
        }
    }

    /**
     * Evaluate expression and return opaque type
     *
     * @param cexp cexp
     * @param ctx ctx
     * @param type type
     *
     * @return type
     *
     * @throws FaultException FaultException
     * @throws EvaluationException EvaluationException
     */
    private Object evaluate(OExpression cexp, EvaluationContext ctx, QName type)
        throws FaultException, EvaluationException {
        try {
            OXQuery10ExpressionBPEL20 oxquery10 = ((OXQuery10ExpressionBPEL20) cexp);

            XQDataSource xqds = new SaxonXQDataSource();
            XQConnection xqconn = xqds.getConnection();

            Configuration configuration = ((SaxonXQConnection) xqconn).getConfiguration();
            configuration.setAllNodesUntyped(true);
            configuration.setHostLanguage(Configuration.XQUERY);

            XQStaticContext staticEnv = xqconn.getStaticContext();

            NSContext nsContext = oxquery10.getNamespaceCtx();
            Set<String> prefixes = nsContext.getPrefixes();
            for (String prefix : prefixes) {
                String uri = nsContext.getNamespaceURI(prefix);
                staticEnv.declareNamespace(prefix, uri);
            }

            configuration.setSchemaValidationMode(Validation.SKIP);
            xqconn.setStaticContext(staticEnv);

            // Prepare expression, for starters
            String xquery = oxquery10.getXquery().replaceFirst(
                    Constants.XQUERY_FUNCTION_HANDLER_COMPILER,
                    Constants.XQUERY_FUNCTION_HANDLER_RUNTIME);
            XQPreparedExpression exp = xqconn.prepareExpression(xquery);

            JaxpFunctionResolver funcResolver = new JaxpFunctionResolver(ctx,
                    oxquery10);
            JaxpVariableResolver variableResolver = new JaxpVariableResolver(ctx,
                    oxquery10, configuration);
            // Bind external variables to runtime values
            for (QName variable : exp.getAllUnboundExternalVariables()) {
                // Evaluate referenced variable
                Object value = variableResolver.resolveVariable(variable);

                 if (value instanceof Value) {
                     SaxonXQConnection saxonConn = (SaxonXQConnection) xqconn;
                     try {
                         Item item = ((Value) value).asItem();
                         if (item == null) {
                             exp.bindSequence(variable, xqconn.createSequence(Collections.EMPTY_LIST.iterator()));
                         } else {
                             XQItem item2 = new SaxonXQItem(item, saxonConn);
                             exp.bindItem(variable, item2);
                         }
                     } catch (XPathException e) {
                         __log.warn("", e);
                     }
                 } else {

                     if (value instanceof Date) {
                         Date d = (Date) value;
                         value = org.apache.ode.utils.ISO8601DateParser.format(d);
                     }

                     // Figure out type of variable
                     XQSequenceType xqType = getItemType(xqconn, value);

                     // Saxon doesn't like binding sequences to variables
                     if (value instanceof Node) {
                         // a node is a node-list, but the inverse isn't true.
                         // so, if the value is truly a node, leave it alone.
                     } else if (value instanceof NodeList) {
                         // So extract the first item from the node list
                         NodeList nodeList = (NodeList) value;
                         ArrayList nodeArray = new ArrayList();
                         for (int i = 0; i < nodeList.getLength(); i++) {
                             nodeArray.add(nodeList.item(i));
                         }
                         value = xqconn.createSequence(nodeArray.iterator());
                     }

                     // Bind value with external variable
                     if (value != null && xqType != null) {
                         if (value instanceof XQSequence) {
                             exp.bindSequence(variable, (XQSequence) value);
                         } else {
                             if (xqType instanceof XQItemType) {
                                 exp.bindObject(variable, value, (XQItemType) xqType);
                             }
                         }
                     }
                  }
            }

            // Set context node
            Node contextNode = (ctx.getRootNode() == null)
                ? DOMUtils.newDocument() : ctx.getRootNode();
            contextNode.setUserData(XQuery10BpelFunctions.USER_DATA_KEY_FUNCTION_RESOLVER,
                funcResolver, null);
            exp.bindItem(XQConstants.CONTEXT_ITEM,
                xqconn.createItemFromNode(contextNode, xqconn.createNodeType()));

            // Execute query
            XQResultSequence result = exp.executeQuery();

            // Cast Saxon result to Java result
            Object evalResult = getResultValue(type, result);

            if ((evalResult != null) && __log.isDebugEnabled()) {
                __log.debug("Expression " + cexp.toString() +
                    " generated result " + evalResult + " - type=" +
                    evalResult.getClass().getName());

                if (ctx.getRootNode() != null) {
                    __log.debug("Was using context node " +
                        DOMUtils.domToString(ctx.getRootNode()));
                }
            }

            return evalResult;
        } catch (XQException xqe) {
            // Extracting the real cause from all this wrapping isn't a simple task
            Throwable cause = (xqe.getCause() != null) ? xqe.getCause() : xqe;

            if (cause instanceof DynamicError) {
                Throwable th = ((DynamicError) cause).getException();

                if (th != null) {
                    cause = th;

                    if (cause.getCause() != null) {
                        cause = cause.getCause();
                    }
                }
            }

            throw new EvaluationException(
                "Error while executing an XQuery expression: " + cause.toString(), cause);
        } catch (WrappedResolverException wre) {
            __log.debug("Could not evaluate expression because of ", wre);
            throw (FaultException) wre.getCause();
        }
    }

    /**
     * Return opaque object embedded in XQuery Item
     *
     * @param item item
     *
     * @return type
     *
     * @throws XQException XQException
     */
    private Object getItemValue(XQItem item) throws XQException {
        XQItemType itemType = item.getItemType();
        Object itemValue = null;

        switch (itemType.getBaseType()) {
        case XQItemType.XQBASETYPE_BOOLEAN:
            itemValue = item.getBoolean();

            break;

        case XQItemType.XQBASETYPE_DECIMAL:
            itemValue = item.getDouble();

            break;

        case XQItemType.XQBASETYPE_BYTE:
            itemValue = item.getByte();

            break;

        case XQItemType.XQBASETYPE_FLOAT:
            itemValue = item.getFloat();

            break;

        case XQItemType.XQBASETYPE_INT:
        case XQItemType.XQBASETYPE_INTEGER:
            itemValue = item.getInt();

            break;

        case XQItemType.XQBASETYPE_LONG:
            itemValue = item.getLong();

            break;

        case XQItemType.XQBASETYPE_ANYTYPE:
            itemValue = item.getNode();

            break;

        case XQItemType.XQBASETYPE_ANYURI:
            itemValue = item.getNodeUri();

            break;

        case XQItemType.XQBASETYPE_SHORT:
            itemValue = item.getShort();

            break;

        case XQItemType.XQBASETYPE_STRING:
        case XQItemType.XQBASETYPE_ANYATOMICTYPE:
            itemValue = item.getAtomicValue();

            break;

        }

        return itemValue;
    }

    /**
     * Return XQuery type corresponding to given value
     *
     * @param xqconn XQuery connection
     * @param value value
     *
     * @return type
     *
     * @throws XQException XQException
     */
    private XQSequenceType getItemType(XQConnection xqconn, Object value) throws XQException {
        XQSequenceType xqType = null;
        if (value instanceof Long) {
            xqType = xqconn.createAtomicType(XQItemType.XQBASETYPE_LONG);
        } else if (value instanceof String) {
            xqType = xqconn.createAtomicType(XQItemType.XQBASETYPE_STRING);
        } else if (value instanceof Boolean) {
            xqType = xqconn.createAtomicType(XQItemType.XQBASETYPE_BOOLEAN);
        } else if (value instanceof Date) {
            xqType = xqconn.createAtomicType(XQItemType.XQBASETYPE_DATETIME);
        } else if (value instanceof BigDecimal) {
            xqType = xqconn.createAtomicType(XQItemType.XQBASETYPE_DECIMAL);
        } else if (value instanceof Float) {
            xqType = xqconn.createAtomicType(XQItemType.XQBASETYPE_FLOAT);
        } else if (value instanceof URI) {
            xqType = xqconn.createAtomicType(XQItemType.XQBASETYPE_ANYURI);
        } else if (value instanceof QName) {
            xqType = xqconn.createAtomicType(XQItemType.XQBASETYPE_QNAME);
        } else if (value instanceof BigInteger) {
            xqType = xqconn.createAtomicType(XQItemType.XQBASETYPE_INT);
        } else if (value instanceof Integer) {
            xqType = xqconn.createAtomicType(XQItemType.XQBASETYPE_INTEGER);
        } else if (value instanceof Double) {
            xqType = xqconn.createAtomicType(XQItemType.XQBASETYPE_DOUBLE);
        } else if (value instanceof Byte) {
            xqType = xqconn.createAtomicType(XQItemType.XQBASETYPE_BYTE);
        } else if (value instanceof Node) {
            xqType = xqconn.createNodeType();
        } else if (value instanceof NodeList || value instanceof XQSequence) {
            XQItemType xqItemType = xqconn.createNodeType();
            xqType = xqconn.createSequenceType(xqItemType, XQSequenceType.OCC_ZERO_OR_MORE);
        }
        return xqType;
    }

    /**
     * Cast XQuery sequence into an opaque list
     *
     * @param type type
     * @param result result
     *
     * @return value
     *
     * @throws XQException XQException
     */
    private Object getResultValue(QName type, XQResultSequence result) throws XQException {
        Document document = DOMUtils.newDocument();
        Object resultValue = null;
        if (XPathConstants.NODESET.equals(type)) {
            List list = new ArrayList();

            while (result.next()) {
                Object itemValue = getItemValue(result.getItem());
                if (itemValue instanceof Document) {
                    itemValue = DOMUtils.cloneNode(document, ((Document) itemValue).getDocumentElement());
                } else if (itemValue instanceof Node) {
                    itemValue = DOMUtils.cloneNode(document, (Node) itemValue);
                }

                if (itemValue != null) {
                    list.add(itemValue);
                }
            }

            resultValue = list;
        } else if (XPathConstants.NODE.equals(type)) {
            XQItem item = null;
            if (result.count() > 0) {
                result.first();
                if (result.isOnItem()) {
                    item = result.getItem();
                }
            }
            if (item != null) {
                resultValue = getItemValue(item);
                if (resultValue instanceof Node) {
                    resultValue = DOMUtils.cloneNode(document, (Node) resultValue);
                }
            }
        } else if (XPathConstants.STRING.equals(type)) {
            resultValue = result.getSequenceAsString(new Properties());
        } else if (XPathConstants.NUMBER.equals(type)) {
            resultValue = result.getSequenceAsString(new Properties());
            resultValue = Integer.parseInt((String) resultValue);
        } else if (XPathConstants.BOOLEAN.equals(type)) {
            resultValue = result.getSequenceAsString(new Properties());
            resultValue = Boolean.parseBoolean((String) resultValue);
        }
        return resultValue;
    }
}
