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

import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerFactory;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQConstants;
import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQItemType;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQSequence;
import javax.xml.xquery.XQStaticContext;

import net.sf.saxon.Configuration;
import net.sf.saxon.om.Validation;
import net.sf.saxon.xqj.SaxonXQConnection;
import net.sf.saxon.xqj.SaxonXQDataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ode.bpel.compiler.api.CompilationException;
import org.apache.ode.bpel.compiler.api.CompilerContext;
import org.apache.ode.bpel.compiler.api.ExpressionCompiler;
import org.apache.ode.bpel.compiler.bom.Expression;
import org.apache.ode.bpel.elang.xpath10.compiler.XPathMessages;
import org.apache.ode.bpel.elang.xpath10.compiler.XslCompilationErrorListener;
import org.apache.ode.bpel.elang.xpath20.compiler.Constants;
import org.apache.ode.bpel.elang.xpath20.compiler.JaxpFunctionResolver;
import org.apache.ode.bpel.elang.xpath20.compiler.JaxpVariableResolver;
import org.apache.ode.bpel.elang.xpath20.compiler.WrappedResolverException;
import org.apache.ode.bpel.elang.xquery10.obj.OXQuery10ExpressionBPEL20;
import org.apache.ode.bpel.obj.OConstantVarType;
import org.apache.ode.bpel.obj.OElementVarType;
import org.apache.ode.bpel.obj.OExpression;
import org.apache.ode.bpel.obj.OLValueExpression;
import org.apache.ode.bpel.obj.OMessageVarType;
import org.apache.ode.bpel.obj.OScope;
import org.apache.ode.bpel.obj.OVarType;
import org.apache.ode.bpel.obj.OXsdTypeVarType;
import org.apache.ode.bpel.obj.OMessageVarType.Part;
import org.apache.ode.utils.DOMUtils;
import org.apache.ode.utils.NSContext;
import org.apache.ode.utils.Namespaces;
import org.apache.ode.utils.msg.MessageBundle;
import org.apache.ode.utils.xsl.XslTransformHandler;
import org.apache.xml.utils.XMLChar;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * XQuery compiler based on the SAXON implementation.
 */
public class XQuery10ExpressionCompilerImpl implements ExpressionCompiler {

    protected static final Log __log = LogFactory.getLog(XQuery10ExpressionCompilerImpl.class);

    protected String _bpelNS;
    protected QName _qnLinkStatus;
    protected QName _qnVarProp;
    protected QName _qnVarData;
    protected QName _qnXslTransform;

    protected final XPathMessages __msgs = MessageBundle.getMessages(XPathMessages.class);
    protected Map<String, String> _properties = new HashMap<String, String>();
    protected CompilerContext _compilerContext;

    public XQuery10ExpressionCompilerImpl(String bpelNS) {
        _bpelNS = bpelNS;
        _qnLinkStatus = new QName(_bpelNS, Constants.EXT_FUNCTION_GETLINKSTATUS);
        _qnVarProp = new QName(_bpelNS, Constants.EXT_FUNCTION_GETVARIABLEPROPERTY);
        _qnVarData = new QName(_bpelNS, Constants.EXT_FUNCTION_GETVARIABLEDATA);
        _qnXslTransform = new QName(_bpelNS, Constants.EXT_FUNCTION_DOXSLTRANSFORM);

        _properties.put("runtime-class", "org.apache.ode.bpel.elang.xquery10.runtime.XQuery10ExpressionRuntime");
        TransformerFactory trsf = new net.sf.saxon.TransformerFactoryImpl();
        XslTransformHandler.getInstance().setTransformerFactory(trsf);
    }

    public void setCompilerContext(CompilerContext compilerContext) {
        _compilerContext = compilerContext;
        XslCompilationErrorListener xe = new XslCompilationErrorListener(compilerContext);
        XslTransformHandler.getInstance().setErrorListener(xe);
    }

    /**
     * @see org.apache.ode.bpel.compiler.api.ExpressionCompiler#compileJoinCondition(java.lang.Object)
     */
    public OExpression compileJoinCondition(Object source) throws CompilationException {
        return _compile((Expression) source, true);
    }

    /**
     * @see org.apache.ode.bpel.compiler.api.ExpressionCompiler#compile(java.lang.Object)
     */
    public OExpression compile(Object source) throws CompilationException {
        return _compile((Expression) source, false);
    }

    /**
     * @see org.apache.ode.bpel.compiler.api.ExpressionCompiler#compileLValue(java.lang.Object)
     */
    public OLValueExpression compileLValue(Object source) throws CompilationException {
        return (OLValueExpression) _compile((Expression) source, false);
    }

    /**
     * @see org.apache.ode.bpel.compiler.api.ExpressionCompiler#compile(java.lang.Object)
     */
    private OExpression _compile(org.apache.ode.bpel.compiler.bom.Expression xquery, boolean isJoinCondition)
            throws CompilationException {
        OXQuery10ExpressionBPEL20 oexp = new OXQuery10ExpressionBPEL20(_compilerContext.getOProcess(), _qnVarData,
                _qnVarProp, _qnLinkStatus, _qnXslTransform, isJoinCondition);
        oexp.setNamespaceCtx(xquery.getNamespaceContext());
        doJaxpCompile(oexp, xquery);
        return oexp;
    }

    private void doJaxpCompile(OXQuery10ExpressionBPEL20 out, Expression source) throws CompilationException {
        String xqueryStr;
        Node node = source.getExpression();
        if (node == null) {
            throw new CompilationException(__msgs.errEmptyExpression(source.getURI(), new QName(source.getElement().getNamespaceURI(), source.getElement().getNodeName())));
        }
        if (node.getNodeType() != Node.TEXT_NODE &&
                node.getNodeType() != Node.ELEMENT_NODE &&
                node.getNodeType() != Node.CDATA_SECTION_NODE) {
            throw new CompilationException(__msgs.errUnexpectedNodeTypeForXPath(DOMUtils.domToString(node)));
        }
        xqueryStr = DOMUtils.domToString(node);
        xqueryStr = xqueryStr.trim();
        if (xqueryStr.length() == 0) {
            throw new CompilationException(__msgs.warnXPath20Syntax(DOMUtils.domToString(node), "empty string"));
        }

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

            __log.debug("Compiling expression " + xqueryStr);
            Configuration configuration = ((SaxonXQConnection) xqconn).getConfiguration();
            configuration.setAllNodesUntyped(true);
            configuration.setHostLanguage(Configuration.XQUERY);

            XQStaticContext staticContext = xqconn.getStaticContext();
            JaxpFunctionResolver funcResolver = new JaxpFunctionResolver(
                    _compilerContext, out, source.getNamespaceContext(), _bpelNS);
            JaxpVariableResolver variableResolver = new JaxpVariableResolver(
                    _compilerContext, out);

            XQueryDeclarations declarations = new XQueryDeclarations();
            NSContext nsContext = source.getNamespaceContext();
            Set<String> prefixes = nsContext.getPrefixes();
            if (!nsContext.getUriSet().contains(Namespaces.ODE_EXTENSION_NS)) {
                nsContext.register("ode", Namespaces.ODE_EXTENSION_NS);
            }
            for (String prefix : prefixes) {
                String uri = nsContext.getNamespaceURI(prefix);
                staticContext.declareNamespace(prefix, uri);
                if ("".equals(prefix)) {
                    declarations.declareDefaultElementNamespace(uri);
                } else if ("bpws".equals(prefix)) {
                    declarations.declareNamespace("bpws", "java:" + Constants.XQUERY_FUNCTION_HANDLER_COMPILER);
                } else {
                    declarations.declareNamespace(prefix, uri);
                }
            }
            declarations.declareVariable(
                    getQName(nsContext, Namespaces.ODE_EXTENSION_NS, "pid"),
                    getQName(nsContext, Namespaces.XML_SCHEMA, "integer"));
//            Map<URI, Source> schemaDocuments = _compilerContext.getSchemaSources();
//            for (URI schemaUri : schemaDocuments.keySet()) {
//            	Source schemaSource = schemaDocuments.get(schemaUri);
//            	// Don't add schema sources, since our Saxon library is not schema-aware.
//            	// configuration.addSchemaSource(schemaSource);
//            }
            configuration.setSchemaValidationMode(Validation.SKIP);
            List<OScope.Variable> variables = _compilerContext.getAccessibleVariables();
            Map<QName, QName> variableTypes = new HashMap<QName, QName>();
            for (String variableName : getVariableNames(xqueryStr)) {
                OScope.Variable variable = getVariable(variables, variableName);
                if (variable == null) {
                    continue;
                }
                OVarType type = variable.getType();
                QName nameQName = getNameQName(variableName);
                QName typeQName = getTypeQName(variableName, type);
                variableTypes.put(nameQName, typeQName);
                String prefix = typeQName.getPrefix();
                if (prefix == null || "".equals(prefix.trim())) {
                    prefix = getPrefixForUri(nsContext, typeQName.getNamespaceURI());
                }
                // don't declare typed variables, as our engine is not schema-aware
                // declarations.declareVariable(variable.name, typeQName);
                declarations.declareVariable(variableName);
            }

            // Add implicit declarations as prolog to the user-defined XQuery
            out.setXquery((declarations.toString()) + xqueryStr);

            // Check the XQuery for compilation errors
            xqconn.setStaticContext(staticContext);
            XQPreparedExpression exp = xqconn.prepareExpression(out.getXquery());

            // Pre-evaluate variables and functions by executing query
            node.setUserData(XQuery10BpelFunctions.USER_DATA_KEY_FUNCTION_RESOLVER,
                    funcResolver, null);
            exp.bindItem(XQConstants.CONTEXT_ITEM,
                    xqconn.createItemFromNode(node, xqconn.createNodeType()));
            // Bind external variables to dummy runtime values
            for (QName variable : exp.getAllUnboundExternalVariables()) {
                QName typeQName = variableTypes.get(variable);
                Object value = variableResolver.resolveVariable(variable);
                if (typeQName != null) {
                    if (value.getClass().getName().startsWith("java.lang")) {
                        exp.bindAtomicValue(variable, value.toString(),
                                xqconn.createAtomicType(XQItemType.XQBASETYPE_ANYATOMICTYPE));
                    } else if (value instanceof Node) {
                        exp.bindNode(variable, (Node) value, xqconn.createNodeType());
                    } else if (value instanceof NodeList) {
                        NodeList nodeList = (NodeList) value;
                        ArrayList nodeArray = new ArrayList();
                        for (int i = 0; i < nodeList.getLength(); i++) {
                            nodeArray.add(nodeList.item(i));
                        }
                        XQSequence sequence = xqconn.createSequence(nodeArray.iterator());
                        exp.bindSequence(variable, sequence);
                    }
                }
            }
            // evaluate the expression so as to initialize the variables
            try {
                exp.executeQuery();
            } catch (XQException xpee) {
                // swallow errors caused by uninitialized variables
            } finally {
                // reset the expression's user data, in order to avoid
                // serializing the function resolver in the compiled bpel file.
                if (node != null) {
                    node.setUserData(XQuery10BpelFunctions.USER_DATA_KEY_FUNCTION_RESOLVER, null, null);
                }
            }
        } catch (XQException xqe) {
            __log.debug(xqe);
            __log.info("Couldn't validate properly expression " + xqueryStr);
            throw new CompilationException(__msgs.errXQuery10Syntax(xqueryStr, "Couldn't validate XQuery expression"));
        } catch (WrappedResolverException wre) {
            if (wre._compilationMsg != null)
                throw new CompilationException(wre._compilationMsg, wre);
            if (wre.getCause() instanceof CompilationException)
                throw (CompilationException) wre.getCause();
            throw wre;
        }
    }

    public Map<String, String> getProperties() {
        return _properties;
    }

    private String getQName(NSContext nsContext, String uri, String localPart) {
        String prefix = getPrefixForUri(nsContext, uri);
        return (prefix == null ? localPart : (prefix + ":" + localPart));
    }

    private String getPrefixForUri(NSContext nsContext, String uri) {
        Set<String> prefixes = nsContext.getPrefixes();
        for (String prefix : prefixes) {
            String anUri = (nsContext.getNamespaceURI(prefix));
            if (anUri != null && anUri.equals(uri)) {
                return prefix;
            }
        }
        return null;
    }

    protected static Collection<String> getVariableNames(String xquery) {
        Collection<String> variableNames = new LinkedHashSet<String>();
        for (int index = xquery.indexOf("$"); index != -1; index = xquery.indexOf("$")) {
            StringBuilder variableName = new StringBuilder();
            index++;
            while(index < xquery.length() && XMLChar.isNCName(xquery.charAt(index))) {
                variableName.append(xquery.charAt(index++));
            }
            variableNames.add(variableName.toString());
            xquery = xquery.substring(index);
        }
        return variableNames;
    }

    private OScope.Variable getVariable(List<OScope.Variable> variables, String variableName) {
        String declaredVariable = getVariableDeclaredName(variableName);
        for (OScope.Variable variable : variables) {
            if (variable.getName().equals(declaredVariable)) {
                return variable;
            }
        }
        return null;
    }

    private String getVariableDeclaredName(String variableReference) {
        int dotIndex = variableReference.indexOf(".");
        return dotIndex >= 0 ? variableReference.substring(0, dotIndex) : variableReference;
    }

    private String getVariablePartName(String variableReference) {
        int dotIndex = variableReference.indexOf(".");
        return dotIndex >= 0 ? variableReference.substring(dotIndex + 1) : "";
    }

    private QName getNameQName(String variableName) {
        String prefix = null, localName = null;;
        int colonIndex = variableName.indexOf(":");
        if (colonIndex >= 0) {
            prefix = variableName.substring(0, colonIndex);
            localName = variableName.substring(colonIndex + 1);
        } else {
            prefix = "";
            localName = variableName;
        }
        return new QName(prefix, localName);
    }

    private QName getTypeQName(String variableName, OVarType type) {
        QName typeQName = null;
        if (type instanceof OConstantVarType) {
            typeQName = new QName(Namespaces.XML_SCHEMA, "string", "xs");
        } else if (type instanceof OElementVarType) {
            typeQName = ((OElementVarType) type).getElementType();
        } else if (type instanceof OMessageVarType) {
            Part part = ((OMessageVarType) type).getParts().get(getVariablePartName(variableName));
            if (part != null) {
                typeQName = getTypeQName(variableName, part.getType());
            }
        } else if (type instanceof OXsdTypeVarType) {
            typeQName = ((OXsdTypeVarType) type).getXsdType();
        }
        return typeQName;
    }

    private static class XQueryDeclarations {
        StringBuffer declarations = new StringBuffer();

        public XQueryDeclarations() {}

        public void declareVariable(String name, QName type) {
            declareVariable(name, type.getPrefix() + ":" + type.getLocalPart());
        }

        public void declareVariable(String name, String type) {
            declarations.append("declare variable ")
                .append("$")
                .append(name)
                .append(" as ")
                .append(type)
                .append(" external ")
                .append(";\n");
        }

        public void declareVariable(String name) {
            declarations.append("declare variable ")
                .append("$")
                .append(name)
                .append(" external ")
                .append(";\n");
        }

        public void declareNamespace(String prefix, String uri) {
            declarations.append("declare namespace ")
                .append(prefix)
                .append("=")
                .append("\"" + uri + "\"")
                .append(";\n");
        }

        public void declareDefaultElementNamespace(String uri) {
            declarations.append("declare default element namespace ")
                .append("\"" + uri + "\"")
                .append(";\n");
        }

        public String toString() {
            return declarations.toString();
        }
    }
}
