/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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.xmlbeans.impl.store;

import org.apache.xmlbeans.*;
import org.apache.xmlbeans.impl.common.DefaultClassLoaderResourceLoader;
import org.apache.xmlbeans.impl.common.XPath;
import org.w3c.dom.*;

import javax.xml.namespace.QName;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Date;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;

public abstract class Query
{
    public static final String QUERY_DELEGATE_INTERFACE = "QUERY_DELEGATE_INTERFACE";
    public static String _useDelegateForXQuery = "use delegate for xquery";
    public static String _useXdkForXQuery = "use xdk for xquery";

    private static String _delIntfName;
    //private static HashMap _delegateQueryCache = new HashMap();

    private static HashMap _xdkQueryCache = new HashMap();
    private static Method _xdkCompileQuery;
    private static boolean _xdkAvailable = true;  // at the beginning assume is available

    private static HashMap _xqrlQueryCache = new HashMap(); //todo check for memory leaks
    private static Method _xqrlCompileQuery;
    private static boolean _xqrlAvailable = true;  // at the beginning assume is available

    private static HashMap _xqrl2002QueryCache = new HashMap();
    private static Method  _xqrl2002CompileQuery;
    private static boolean _xqrl2002Available = true;  // at the beginning assume is available

    static
    {
        String id = "META-INF/services/org.apache.xmlbeans.impl.store.QueryDelegate.QueryInterface";
        InputStream in = new DefaultClassLoaderResourceLoader().getResourceAsStream(id);
        try
        {
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            _delIntfName = br.readLine().trim();
            br.close();
        }
        catch (Exception e)
        {
            _delIntfName = null;
        }
    }

    abstract XmlObject[] objectExecute(Cur c, XmlOptions options);

    abstract XmlCursor cursorExecute(Cur c, XmlOptions options);

    //
    // Xqrl store specific implementation of compiled path/query
    //

    static XmlObject[] objectExecQuery(Cur c, String queryExpr, XmlOptions options)
    {
        return getCompiledQuery(queryExpr, options).objectExecute(c, options);
    }

    static XmlCursor cursorExecQuery(Cur c, String queryExpr, XmlOptions options)
    {
        return getCompiledQuery(queryExpr, options).cursorExecute(c, options);
    }

    public static synchronized Query getCompiledQuery(String queryExpr, XmlOptions options)
    {
        return getCompiledQuery(queryExpr, Path.getCurrentNodeVar(options), options);
    }

    static synchronized Query getCompiledQuery(String queryExpr, String currentVar, XmlOptions options)
    {
        assert queryExpr != null;
        options = XmlOptions.maskNull(options);
        Query query;

        if (options.hasOption(Path._forceXqrl2002ForXpathXQuery))
        {
            query = (Query)_xqrl2002QueryCache.get(queryExpr);
            if (query!=null)
                return query;

            query = getXqrl2002CompiledQuery(queryExpr, currentVar);
            if (query!=null)
            {
                _xqrl2002QueryCache.put(queryExpr, query);
                return query;
            }
            throw new RuntimeException("No 2002 query engine found.");
        }

        //Parse the query via XBeans: need to figure out end of prolog
        //in order to bind $this...not good but...
        Map boundary = new HashMap();
        int boundaryVal = 0;
        try
        {
            XPath.compileXPath(queryExpr, currentVar, boundary);
        }
        catch (XPath.XPathCompileException e)
        {
            //don't care if it fails, just care about boundary
        }
        finally
        {
            boundaryVal = boundary.get(XPath._NS_BOUNDARY) == null ? 0 :
                ((Integer) boundary.get(XPath._NS_BOUNDARY)).intValue();
        }

        if (options.hasOption(_useXdkForXQuery))
        {
            //try XDK
            query = (Query) _xdkQueryCache.get(queryExpr);
            if (query != null)
                return query;

            query = createXdkCompiledQuery(queryExpr, currentVar);
            if (query != null)
            {
                _xdkQueryCache.put(queryExpr, query);
                return query;
            }
        }

        if (!options.hasOption(_useDelegateForXQuery))
        {
        //try XQRL
        query = (Query) _xqrlQueryCache.get(queryExpr);
        if (query != null)
            return query;

        query = createXqrlCompiledQuery(queryExpr, currentVar);
        if (query != null)
        {
            _xqrlQueryCache.put(queryExpr, query);
            return query;
        }
        }

        //otherwise (if _useDelegateForXQuery option is set), 
        //or if xqrl is not found, try delegate
        //query = (Query) _delegateQueryCache.get(queryExpr);

        //if (query != null)
        //    return query;

        String delIntfName = 
            options.hasOption(QUERY_DELEGATE_INTERFACE) ? 
                (String)options.get(QUERY_DELEGATE_INTERFACE) : _delIntfName;
        query = DelegateQueryImpl.createDelegateCompiledQuery(delIntfName, queryExpr, currentVar, boundaryVal, options);

        if (query != null)
        {
            //_delegateQueryCache.put(queryExpr, query);
            return query;
        }

        throw new RuntimeException("No query engine found");
    }

    public static synchronized String compileQuery(String queryExpr, XmlOptions options)
    {
        getCompiledQuery(queryExpr, options);
        return queryExpr;
    }

    private static Query createXdkCompiledQuery(String queryExpr, String currentVar)
    {
        //if the XDK engine has been determined unavailable, return null
        if ( !_xdkAvailable ) return null;
        if ( _xdkCompileQuery == null)
        {
            try
            {
                Class xdkImpl = Class.forName("org.apache.xmlbeans.impl.store.OXQXBXqrlImpl");

                _xdkCompileQuery =
                    xdkImpl.getDeclaredMethod("compileQuery",
                        new Class[]{String.class, String.class, Boolean.class});
            }
            catch (ClassNotFoundException e)
            {
                _xdkAvailable = false;
                return null;
            }
            catch (Exception e)
            {
                _xdkAvailable = false;
                throw new RuntimeException(e.getMessage(), e);
            }
        }

        Object[] args = new Object[]{queryExpr, currentVar, new Boolean(true)};

        try
        {
            return (Query) _xdkCompileQuery.invoke(null, args);
        }
        catch (InvocationTargetException e)
        {
            Throwable t = e.getCause();
            throw new RuntimeException(t.getMessage(), t);
        }
        catch (IllegalAccessException e)
        {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    private static Query createXqrlCompiledQuery(String queryExpr, String currentVar)
    {
        //if the XQRL engine has been determined unavailable, return null
        if ( !_xqrlAvailable ) return null;
        if ( _xqrlCompileQuery == null)
        {
            try
            {
                Class xqrlImpl = Class.forName("org.apache.xmlbeans.impl.store.XqrlImpl");

                _xqrlCompileQuery =
                        xqrlImpl.getDeclaredMethod("compileQuery",
                                new Class[]{String.class, String.class, Boolean.class});
            }
            catch (ClassNotFoundException e)
            {
                _xqrlAvailable = false;
                return null;
            }
            catch (Exception e)
            {
                _xqrlAvailable = false;
                throw new RuntimeException(e.getMessage(), e);
            }
        }

        Object[] args = new Object[]{queryExpr, currentVar, new Boolean(true)};

        try
        {
            return (Query) _xqrlCompileQuery.invoke(null, args);
        }
        catch (InvocationTargetException e)
        {
            Throwable t = e.getCause();
            throw new RuntimeException(t.getMessage(), t);
        }
        catch (IllegalAccessException e)
        {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    private static Query getXqrl2002CompiledQuery(String queryExpr, String currentVar)
    {
        if (_xqrl2002Available && _xqrl2002CompileQuery == null)
        {
            try
            {
                Class xqrlImpl = Class.forName("org.apache.xmlbeans.impl.store.Xqrl2002Impl");

                _xqrl2002CompileQuery =
                        xqrlImpl.getDeclaredMethod("compileQuery",
                                new Class[]{String.class, String.class, Boolean.class});
            }
            catch (ClassNotFoundException e)
            {
                _xqrl2002Available = false;
                return null;
            }
            catch (Exception e)
            {
                _xqrl2002Available = false;
                throw new RuntimeException(e.getMessage(), e);
            }
        }

        Object[] args = new Object[]{queryExpr, currentVar, new Boolean(true)};

        try
        {
            return (Query) _xqrl2002CompileQuery.invoke(null, args);
        }
        catch (InvocationTargetException e)
        {
            Throwable t = e.getCause();
            throw new RuntimeException(t.getMessage(), t);
        }
        catch (IllegalAccessException e)
        {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    private static final class DelegateQueryImpl extends Query
    {
        private DelegateQueryImpl(QueryDelegate.QueryInterface xqueryImpl)
        {
            _xqueryImpl = xqueryImpl;
        }

        static Query createDelegateCompiledQuery(String delIntfName,
                                                 String queryExpr,
                                                 String currentVar,
                                                 int boundary,
                                                 XmlOptions xmlOptions)
        {
            assert !(currentVar.startsWith(".") || currentVar.startsWith(".."));
            QueryDelegate.QueryInterface impl =
                QueryDelegate.createInstance(delIntfName, queryExpr,
                                             currentVar, boundary, xmlOptions);
            if (impl == null)
                return null;

            return new DelegateQueryImpl(impl);
        }

        XmlObject[] objectExecute(Cur c, XmlOptions options)
        {
            return new DelegateQueryEngine(_xqueryImpl, c, options).objectExecute();
        }

        XmlCursor cursorExecute(Cur c, XmlOptions options)
        {
            return new DelegateQueryEngine(_xqueryImpl, c, options).cursorExecute();
        }


        private static class DelegateQueryEngine
        {
            public DelegateQueryEngine(QueryDelegate.QueryInterface xqImpl,
                                    Cur c, XmlOptions opt)
            {

                _engine = xqImpl;
                _version = c._locale.version();
                _cur = c.weakCur(this);
                _options = opt;

            }

            public XmlObject[] objectExecute()
            {
                if (_cur != null && _version != _cur._locale.version())
                //throw new ConcurrentModificationException
                // ("Document changed during select")
                    ;

                Map bindings = (Map) XmlOptions.maskNull(_options).
                    get(XmlOptions.XQUERY_VARIABLE_MAP);
                List resultsList;
                resultsList = _engine.execQuery(_cur.getDom(), bindings);

                assert resultsList.size() > -1;

                XmlObject[] result = new XmlObject[resultsList.size()];
                int i;
                for (i = 0; i < resultsList.size(); i++) {
                    //copy objects into the locale
                    Locale l = Locale.getLocale(_cur._locale._schemaTypeLoader,
                            _options);

                    l.enter();
                    Object node = resultsList.get(i);
                    Cur res = null;
                    try {
                        //typed function results of XQuery
                        if (!(node instanceof Node)) {
                            //TODO: exact same code as Path.java
                            //make a common super-class and pull this--what to name that
                            //superclass???
                            res = l.load("<xml-fragment/>").tempCur();
                            res.setValue(node.toString());
                            SchemaType type=getType(node);
                            Locale.autoTypeDocument(res, type, null);
                            result[i] = res.getObject();
                        }
                        else
                            res = loadNode(l, (Node) node);
                        result[i] = res.getObject();
                    }
                    catch (XmlException e) {
                        throw new RuntimeException(e);
                    }
                    finally {
                        l.exit();
                    }
                    res.release();
                }
                release();
                _engine = null;
                return result;
            }
            private SchemaType getType(Object node)
            {
                SchemaType type;
                if (node instanceof Integer)
                    type = XmlInteger.type;
                else if (node instanceof Double)
                    type = XmlDouble.type;
                else if (node instanceof Long)
                    type = XmlLong.type;
                else if (node instanceof Float)
                    type = XmlFloat.type;
                else if (node instanceof BigDecimal)
                    type = XmlDecimal.type;
                else if (node instanceof Boolean)
                    type = XmlBoolean.type;
                else if (node instanceof String)
                    type = XmlString.type;
                else if (node instanceof Date)
                    type = XmlDate.type;
                else
                    type = XmlAnySimpleType.type;
                return type;
            }
            public XmlCursor cursorExecute()
            {
                if (_cur != null && _version != _cur._locale.version())
                //throw new ConcurrentModificationException
                // ("Document changed during select")
                    ;

                Map bindings = (Map) XmlOptions.maskNull(_options).
                    get(XmlOptions.XQUERY_VARIABLE_MAP);
                List resultsList;
                resultsList = _engine.execQuery(_cur.getDom(), bindings);

                assert resultsList.size() > -1;

                int i;
                _engine = null;

                Locale locale = Locale.getLocale(_cur._locale._schemaTypeLoader, _options);
                locale.enter();
                Locale.LoadContext _context = new Cur.CurLoadContext(locale, _options);
                Cursor resultCur = null;
                try {
                    for (i = 0; i < resultsList.size(); i++) {
                        loadNodeHelper(locale, (Node) resultsList.get(i), _context);
                    }
                    Cur c = _context.finish();
                    Locale.associateSourceName(c, _options);
                    Locale.autoTypeDocument(c, null, _options);
                    resultCur = new Cursor(c);
                }
                catch (Exception e) {
                }
                finally {
                    locale.exit();
                }
                release();
                return resultCur;
            }


            public void release()
            {
                if (_cur != null) {
                    _cur.release();
                    _cur = null;
                }
            }


            private Cur loadNode(Locale locale, Node node)
            {
                Locale.LoadContext context = new Cur.CurLoadContext(locale, _options);

                try {
                    loadNodeHelper(locale, node, context);
                    Cur c = context.finish();
                    Locale.associateSourceName(c, _options);
                    Locale.autoTypeDocument(c, null, _options);
                    return c;
                }
                catch (Exception e) {
                    throw new XmlRuntimeException(e.getMessage(), e);
                }
            }

            private void loadNodeHelper(Locale locale, Node node, Locale.LoadContext context)
            {
                if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
                        QName attName = new QName(node.getNamespaceURI(),
                            node.getLocalName(),
                            node.getPrefix());
                        context.attr(attName, node.getNodeValue());
                        }
                else
                        locale.loadNode(node, context);

            }


            private Cur _cur;
            private QueryDelegate.QueryInterface _engine;
            private long _version;
            private XmlOptions _options;
        }

        private QueryDelegate.QueryInterface _xqueryImpl;
    }

}
