/*   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.xquery.saxon;

import net.sf.saxon.Configuration;
import net.sf.saxon.dom.DocumentWrapper;
import net.sf.saxon.dom.NodeOverNodeInfo;
import net.sf.saxon.ma.map.HashTrieMap;
import net.sf.saxon.om.Item;
import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.om.StructuredQName;
import net.sf.saxon.query.DynamicQueryContext;
import net.sf.saxon.query.StaticQueryContext;
import net.sf.saxon.query.XQueryExpression;
import net.sf.saxon.type.BuiltInAtomicType;
import net.sf.saxon.value.*;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlRuntimeException;
import org.apache.xmlbeans.XmlTokenSource;
import org.apache.xmlbeans.impl.store.QueryDelegate;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

public class XBeansXQuery
    implements QueryDelegate.QueryInterface {
    private XQueryExpression xquery;
    private String contextVar;
    private Configuration config;

    /**
     * Construct given an XQuery expression string.
     *
     * @param query      The XQuery expression
     * @param contextVar The name of the context variable
     * @param boundary   The offset of the end of the prolog
     */
    public XBeansXQuery(final String query, String contextVar, Integer boundary, XmlOptions xmlOptions) {
        config = new Configuration();
        StaticQueryContext sc = config.newStaticQueryContext();
        Map<String, String> nsMap = xmlOptions.getLoadAdditionalNamespaces();
        if (nsMap != null) {
            nsMap.forEach(sc::declareNamespace);
        }
        this.contextVar = contextVar;
        //Saxon requires external variables at the end of the prolog...
        try {
            xquery = sc.compileQuery(
                query.substring(0, boundary) + " declare variable $" + contextVar + " external;" + query.substring(boundary)
            );
        } catch (TransformerException e) {
            throw new XmlRuntimeException(e);
        }
    }

    public List execQuery(Object node, Map variableBindings) {
        try {
            Node contextNode = (Node) node;

            Document dom = (contextNode.getNodeType() == Node.DOCUMENT_NODE)
                ? (Document) contextNode : contextNode.getOwnerDocument();

            DocumentWrapper docWrapper = new DocumentWrapper(dom, null, config);
            NodeInfo root = docWrapper.wrap(contextNode);

            DynamicQueryContext dc = new DynamicQueryContext(config);
            dc.setContextItem(root);
            dc.setParameter(new StructuredQName("", null, contextVar), root);
            // Set the other variables
            if (variableBindings != null) {
                for (Map.Entry<String, Object> me : ((Map<String, Object>) variableBindings).entrySet()) {
                    StructuredQName key = new StructuredQName("", null, me.getKey());
                    Object value = me.getValue();
                    if (value instanceof XmlTokenSource) {
                        Node paramObject = ((XmlTokenSource) value).getDomNode();
                        dc.setParameter(key, docWrapper.wrap(paramObject));
                    } else {
                        try {
                            dc.setParameter(key, objectToItem(value, config));
                        } catch (XPathException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }

            List<Object> saxonNodes = xquery.evaluate(dc);
            for (ListIterator<Object> it = saxonNodes.listIterator(); it.hasNext(); ) {
                Object o = it.next();
                if (o instanceof NodeInfo) {
                    Node n = NodeOverNodeInfo.wrap((NodeInfo) o);
                    it.set(n);
                }
            }
            return saxonNodes;
        } catch (TransformerException e) {
            throw new RuntimeException("Error binding " + contextVar, e);
        }
    }


    private static Item objectToItem(Object value, Configuration config) throws XPathException, net.sf.saxon.trans.XPathException {
        if (value == null) {
            return null;
        }

        // convert to switch..
        if (value instanceof Boolean) {
            return BooleanValue.get((Boolean) value);
        } else if (value instanceof byte[]) {
            return new HexBinaryValue((byte[]) value);
        } else if (value instanceof Byte) {
            return new Int64Value((Byte) value, BuiltInAtomicType.BYTE, false);
        } else if (value instanceof Float) {
            return new FloatValue((Float) value);
        } else if (value instanceof Double) {
            return new DoubleValue((Double) value);
        } else if (value instanceof Integer) {
            return new Int64Value((Integer) value, BuiltInAtomicType.INT, false);
        } else if (value instanceof Long) {
            return new Int64Value((Long) value, BuiltInAtomicType.LONG, false);
        } else if (value instanceof Short) {
            return new Int64Value((Short) value, BuiltInAtomicType.SHORT, false);
        } else if (value instanceof String) {
            return new StringValue((String) value);
        } else if (value instanceof BigDecimal) {
            return new BigDecimalValue((BigDecimal) value);
        } else if (value instanceof BigInteger) {
            return new BigIntegerValue((BigInteger) value);
        } else if (value instanceof SaxonDuration) {
            return ((SaxonDuration) value).getDurationValue();
        } else if (value instanceof Duration) {
            // this is simpler and safer (but perhaps slower) than extracting all the components
            //return DurationValue.makeDuration(value.toString()).asAtomic();
            Duration dv = (Duration) value;
            return new DurationValue(dv.getSign() >= 0, dv.getYears(), dv.getMonths(), dv.getDays(),
                dv.getHours(), dv.getMinutes(), dv.getSeconds(), 0); // take correct millis..
        } else if (value instanceof SaxonXMLGregorianCalendar) {
            return ((SaxonXMLGregorianCalendar) value).toCalendarValue();
        } else if (value instanceof XMLGregorianCalendar) {
            XMLGregorianCalendar g = (XMLGregorianCalendar) value;
            QName gtype = g.getXMLSchemaType();
            if (gtype.equals(DatatypeConstants.DATETIME)) {
                return DateTimeValue.makeDateTimeValue(value.toString(), config.getConversionRules()).asAtomic();
            } else if (gtype.equals(DatatypeConstants.DATE)) {
                return DateValue.makeDateValue(value.toString(), config.getConversionRules()).asAtomic();
            } else if (gtype.equals(DatatypeConstants.TIME)) {
                return TimeValue.makeTimeValue(value.toString()).asAtomic();
            } else if (gtype.equals(DatatypeConstants.GYEAR)) {
                return GYearValue.makeGYearValue(value.toString(), config.getConversionRules()).asAtomic();
            } else if (gtype.equals(DatatypeConstants.GYEARMONTH)) {
                return GYearMonthValue.makeGYearMonthValue(value.toString(), config.getConversionRules()).asAtomic();
            } else if (gtype.equals(DatatypeConstants.GMONTH)) {
                // a workaround for W3C schema bug
                String val = value.toString();
                if (val.endsWith("--")) {
                    val = val.substring(0, val.length() - 2);
                }
                return GMonthValue.makeGMonthValue(val).asAtomic();
            } else if (gtype.equals(DatatypeConstants.GMONTHDAY)) {
                return GMonthDayValue.makeGMonthDayValue(value.toString()).asAtomic();
            } else if (gtype.equals(DatatypeConstants.GDAY)) {
                return GDayValue.makeGDayValue(value.toString()).asAtomic();
            } else {
                throw new AssertionError("Unknown Gregorian date type");
            }
        } else if (value instanceof QName) {
            QName q = (QName) value;
            return new QNameValue(q.getPrefix(), q.getNamespaceURI(), q.getLocalPart()); //BuiltInAtomicType.QNAME, null);
        } else if (value instanceof URI) {
            return new AnyURIValue(value.toString());
        } else if (value instanceof Map) {
            HashTrieMap htm = new HashTrieMap();
            for (Map.Entry<?, ?> me : ((Map<?, ?>) value).entrySet()) {
                htm.initialPut(
                    (AtomicValue) objectToItem(me.getKey(), config),
                    objectToItem(me.getValue(), config));
            }
            return htm;
        } else {
            return new ObjectValue(value);
        }
    }
}
