/*
 * 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.jena.sparql.algebra;

import java.util.Iterator ;

import org.apache.jena.graph.Graph ;
import org.apache.jena.graph.Node ;
import org.apache.jena.query.ARQ ;
import org.apache.jena.query.Dataset ;
import org.apache.jena.query.Query ;
import org.apache.jena.rdf.model.Model ;
import org.apache.jena.shared.PrefixMapping ;
import org.apache.jena.sparql.algebra.optimize.Optimize ;
import org.apache.jena.sparql.core.DatasetGraph ;
import org.apache.jena.sparql.core.DatasetGraphFactory ;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.engine.Plan ;
import org.apache.jena.sparql.engine.QueryEngineFactory ;
import org.apache.jena.sparql.engine.QueryEngineRegistry ;
import org.apache.jena.sparql.engine.QueryIterator ;
import org.apache.jena.sparql.engine.binding.Binding ;
import org.apache.jena.sparql.engine.binding.BindingFactory ;
import org.apache.jena.sparql.engine.binding.BindingMap ;
import org.apache.jena.sparql.engine.binding.BindingRoot ;
import org.apache.jena.sparql.engine.ref.QueryEngineRef ;
import org.apache.jena.sparql.sse.Item ;
import org.apache.jena.sparql.sse.SSE ;
import org.apache.jena.sparql.sse.builders.BuilderOp ;
import org.apache.jena.sparql.syntax.Element ;
import org.apache.jena.sparql.util.Context ;

/** Utilities to produce SPARQL algebra */
public class Algebra
{
    // -------- Optimize

    /** Apply static transformations to a query to optimize it */
    public static Op optimize(Op op) { return optimize(op, null) ; }

    /** Apply static transformations to a query to optimize it */
    public static Op optimize(Op op, Context context)
    {
        if ( context == null )
            context = ARQ.getContext() ;
        // Call-through to somewhere to manage all the optimizations
        if ( op == null )
            return null ;
        return Optimize.optimize(op, context) ;
    }

    // -------- Compile

    /** Compile a query - pattern and modifiers.  */
    public static Op compile(Query query)
    {
        if ( query == null )
            return null ;
        return new AlgebraGenerator().compile(query) ;
    }

    /** Compile a pattern.*/
    public static Op compile(Element elt)
    {
        if ( elt == null )
            return null ;
        return new AlgebraGenerator().compile(elt) ;
    }

    /** Turn an algebra expression into quadpattern form */
    public static Op toQuadForm(Op op)
    {
        return AlgebraQuad.quadize(op) ;
    }

    /** Turn an algebra expression into quadblock form */
    public static Op toQuadBlockForm(Op op)
    {
        return AlgebraQuad.quadizeBlock(op) ;
    }

    /** Transform an algebra expression so that default graph is union of the named graphs.
     * Does not work with property paths.
     * @deprecated To be removed
     */
    @Deprecated
    public static Op unionDefaultGraph(Op op)
    {
        return TransformUnionQuery.transform(op) ;
    }

    // -------- SSE uses these operations ...

    static public Op read(String filename)
    {
        Item item = SSE.readFile(filename) ;
        return parse(item) ;
    }

    static public Op parse(String string)
    {
        Item item = SSE.parse(string) ;
        return parse(item) ;
    }


    static public Op parse(String string, PrefixMapping pmap)
    {
        Item item = SSE.parse(string, pmap) ;
        return parse(item) ;
    }

    static public Op parse(Item item)
    {
        Op op = BuilderOp.build(item) ;
        return op ;
    }

    // -------- Execute

    static public QueryIterator exec(Op op, Dataset ds)
    {
        return exec(op, ds.asDatasetGraph()) ;
    }

    static public QueryIterator exec(Op op, Model model)
    {
        return exec(op, model.getGraph()) ;
    }

    static public QueryIterator exec(Op op, Graph graph)
    {
        return exec(op, DatasetGraphFactory.wrap(graph)) ;
    }

    static public QueryIterator exec(Op op, DatasetGraph ds)
    {
        QueryEngineFactory f = QueryEngineRegistry.findFactory(op, ds, null) ;
        Plan plan = f.create(op, ds, BindingRoot.create(), null) ;
        return plan.iterator() ;
    }

    //  Reference engine

    static public QueryIterator execRef(Op op, Dataset ds)
    {
        return execRef(op, ds.asDatasetGraph()) ;
    }

    static public QueryIterator execRef(Op op, Model model)
    {
        return execRef(op, model.getGraph()) ;
    }

    static public QueryIterator execRef(Op op, Graph graph)
    {
        return execRef(op, DatasetGraphFactory.wrap(graph)) ;
    }

    static public QueryIterator execRef(Op op, DatasetGraph dsg)
    {
        QueryEngineRef qe = new QueryEngineRef(op, dsg, ARQ.getContext().copy()) ;
        return qe.getPlan().iterator() ;
    }

    // This is the SPARQL merge rule.
    public static Binding merge(Binding bindingLeft, Binding bindingRight)
    {
        // Test to see if compatible: Iterate over variables in left
        boolean matches = compatible(bindingLeft, bindingRight) ;

        if ( ! matches )
            return null ;

        // If compatible, merge. Iterate over variables in right but not in left.
        BindingMap b = BindingFactory.create(bindingLeft) ;
        for ( Iterator<Var> vIter = bindingRight.vars() ; vIter.hasNext() ; )
        {
            Var v = vIter.next();
            Node n = bindingRight.get(v) ;
            if ( ! bindingLeft.contains(v) )
                b.add(v, n) ;
        }
        return b ;
    }

    public static boolean compatible(Binding bindingLeft, Binding bindingRight)
    {
        // Test to see if compatible: Iterate over variables in left
        for ( Iterator<Var> vIter = bindingLeft.vars() ; vIter.hasNext() ; )
        {
            Var v = vIter.next();
            Node nLeft  = bindingLeft.get(v) ;
            Node nRight = bindingRight.get(v) ;

            if ( nRight != null && ! nRight.equals(nLeft) )
                return false ;
        }
        return true ;
    }

    public static boolean disjoint(Binding binding1, Binding binding2)
    {
        Iterator<Var> iterVar1 = binding1.vars() ;
        for ( ; iterVar1.hasNext() ; )
        {
            Var v = iterVar1.next() ;
            if ( binding2.contains(v) )
                return false ;
        }
        return true ;
    }
}
