/*
 * 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.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 Logger __log = LoggerFactory.getLogger(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;
    }
}
