/*
 * 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.ArrayDeque ;
import java.util.Collection ;
import java.util.Deque ;

import org.apache.jena.graph.Node ;
import org.apache.jena.sparql.ARQConstants ;
import org.apache.jena.sparql.algebra.op.* ;
import org.apache.jena.sparql.core.Quad ;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.core.VarAlloc ;

/** 
 * Helper class for converting an algebra expression into a quad form 
 * */
public class AlgebraQuad
{
    // Transform to a quad form:
    //   + BGPs go to quad patterns
    //   + Drop (previous) OpGraph 
    //   + Paths (complex - simple ones are flatten elsewhere) go to (graph (path ...)) [later: quad paths] 

    // Done as a before/after pair to run the stack of graph nodes for rewrite.
    // Need to be careful of use of a variable in GRAPH ?g { .. } and then use ?g inside the pattern.
    
    private AlgebraQuad() { }

    public static Op quadize(Op op)
    {
        final Deque<QuadSlot> stack = new ArrayDeque<>() ;
        QuadSlot qSlot = new QuadSlot(Quad.defaultGraphNodeGenerated, Quad.defaultGraphNodeGenerated) ;  
        stack.push(qSlot) ;             // Starting condition
        
        OpVisitor before = new Pusher(stack) ;
        OpVisitor after = new Popper(stack) ;
        
        TransformQuadGraph qg = new TransformQuadGraph(stack, before, after) ;
        return Transformer.transformSkipService(qg, null, op, before, after) ;
    }
    
    public static Op quadizeBlock(Op op)
    {
        final Deque<QuadSlot> stack = new ArrayDeque<>() ;
        QuadSlot qSlot = new QuadSlot(Quad.defaultGraphNodeGenerated, Quad.defaultGraphNodeGenerated) ;  
        stack.push(qSlot) ;             // Starting condition
        
        OpVisitor before = new Pusher(stack) ;
        OpVisitor after = new Popper(stack) ;
        
        TransformQuadBlockGraph qg = new TransformQuadBlockGraph(stack, before, after) ;
        return Transformer.transformSkipService(qg, null, op, before, after) ;
    }
    
    /** This is the record of the transformation.
     *  The rewriteGraphName is the node to put in the graph slot of the quad.
     *  The actualGraphName is the node used in SPARQL.
     *  If they are the same (by ==), the quadrewrite is OK as is.
     *  If they are different (and that means they are variables)
     *  an assign is done after the execution of the graph pattern block. 
     */
    static class QuadSlot
    {
        // No longer needed (rewriting done elsewhere).
        // Remove and use a stack of Nodes.
        final Node actualGraphName ;
        final Node rewriteGraphName ;
        QuadSlot(Node actualGraphName, Node rewriteGraphName)
        {
            this.actualGraphName = actualGraphName ;
            this.rewriteGraphName = rewriteGraphName ;
        }
        @Override public String toString() { return "actualGraphName="+actualGraphName+" rewriteGraphName="+rewriteGraphName ; } 
    }
    
    private static class Pusher extends OpVisitorBase
    {
        Deque<QuadSlot> stack ;
        VarAlloc varAlloc = new VarAlloc(ARQConstants.allocVarQuad) ;
        Pusher(Deque<QuadSlot> stack) { this.stack = stack ; }
        @Override
        public void visit(OpGraph opGraph)
        {
            // Name in SPARQL
            Node gn = opGraph.getNode() ;
            // Name in rewrite
            Node gnQuad = gn ;
            
            if ( Var.isVar(gn) )
            {
                Collection<Var> vars = OpVars.mentionedVars(opGraph.getSubOp()) ;
                if ( vars.contains(gn) )
                    gnQuad = varAlloc.allocVar() ;
            }
            //System.out.println("Pusher: "+gn) ;
            stack.push(new QuadSlot(gn, gnQuad)) ;
        }
    }
    
    private static class Popper extends OpVisitorBase
    {
        Deque<QuadSlot> stack ;
        Popper(Deque<QuadSlot> stack) { this.stack = stack ; }
        @Override
        public void visit(OpGraph opGraph)
        {
            // The final work is done in the main vistor, 
            // which is called after the subnode has been 
            // rewritten.
            QuadSlot qs = stack.pop() ;
            //System.out.println("Popper: "+qs.rewriteGraphName) ;
        }
    }    
}
