/*
 * 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.ArrayList ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;

import org.apache.jena.graph.Node ;
import org.apache.jena.graph.Triple ;
import org.apache.jena.sparql.algebra.op.OpBGP ;
import org.apache.jena.sparql.algebra.op.OpPropFunc ;
import org.apache.jena.sparql.algebra.op.OpSequence ;
import org.apache.jena.sparql.algebra.op.OpTable ;
import org.apache.jena.sparql.core.BasicPattern ;
import org.apache.jena.sparql.expr.Expr ;
import org.apache.jena.sparql.expr.ExprList ;
import org.apache.jena.sparql.pfunction.PropFuncArg ;
import org.apache.jena.sparql.pfunction.PropertyFunctionRegistry ;
import org.apache.jena.sparql.util.Context ;
import org.apache.jena.sparql.util.ExprUtils ;
import org.apache.jena.sparql.util.graph.GNode ;
import org.apache.jena.sparql.util.graph.GraphList ;

public class PropertyFunctionGenerator
{
    public static Op buildPropertyFunctions(PropertyFunctionRegistry registry, OpBGP opBGP, Context context)
    {
        if ( opBGP.getPattern().isEmpty() )
            return opBGP ;
        return compilePattern(registry, opBGP.getPattern(), context) ;
    }
    
    private static Op compilePattern(PropertyFunctionRegistry registry, BasicPattern pattern, Context context)
    {   
        // Split into triples and property functions.

        // 1/ Find property functions.
        //    Property functions may involve other triples (for list arguments)
        //    (but leave the property function triple in-place as a marker)
        // 2/ Find arguments for property functions
        //    (but leave the property function triple in-place as a marker)
        // 3/ For remaining triples, put into basic graph patterns,
        //    and string together the procedure calls and BGPs.
        
        List<Triple> propertyFunctionTriples = new ArrayList<>() ;    // Property functions seen
        BasicPattern triples = new BasicPattern(pattern) ;  // A copy of all triples (later, it is mutated)
        
        // Find the triples invoking property functions, and those not.
        findPropertyFunctions(context, pattern, registry, propertyFunctionTriples) ;
        
        if ( propertyFunctionTriples.size() == 0 )
            //No property functions.
            return new OpBGP(pattern) ;
        
        Map<Triple, PropertyFunctionInstance> pfInvocations = new HashMap<>() ;  // Map triple => property function instance
        // Removes triples of list arguments.  This mutates 'triples'
        findPropertyFunctionArgs(context, triples, propertyFunctionTriples, pfInvocations) ;
        
        // Now make the OpSequence structure.
        Op op = makeStages(triples, pfInvocations) ;
        return op ;
    }

    private static void findPropertyFunctions(Context context, 
                                              BasicPattern pattern,
                                              PropertyFunctionRegistry registry,
                                              List<Triple> propertyFunctionTriples)
    {
        // Step 1 : find property functions (if any); collect triples.
        // Not list arg triples at this point.
        for ( Triple t : pattern )
        {
            if ( isMagicProperty(registry, t) )
                propertyFunctionTriples.add(t) ;
        }
    }

    
    private static void findPropertyFunctionArgs(Context context, 
                                                 BasicPattern triples,
                                                 List<Triple> propertyFunctionTriples,
                                                 Map<Triple, PropertyFunctionInstance> pfInvocations)
    {
        // Step 2 : for each property function, remove associated triples in list arguments; 
        // Leave the propertyFunction triple itself.

        for ( Triple pf : propertyFunctionTriples )
        {
            PropertyFunctionInstance pfi = magicProperty( context, pf, triples );
            pfInvocations.put( pf, pfi );
        }
    }
    
    private static class PropertyFunctionInstance
    {
        Node predicate ;
        PropFuncArg subjArgs ;
        PropFuncArg objArgs ;
        
         PropertyFunctionInstance(PropFuncArg sArgs, Node predicate, PropFuncArg oArgs)
        {
            this.subjArgs = sArgs ;
            this.predicate = predicate ;
            this.objArgs = oArgs ;
        }
        
        ExprList argList()
        {
            ExprList exprList = new ExprList() ;
            argList(exprList, subjArgs) ;
            argList(exprList, objArgs) ;
            return exprList ;
        }
        
        PropFuncArg getSubjectArgList()     { return subjArgs ; }
        PropFuncArg getObjectArgList()         { return objArgs ; }

        private static void argList(ExprList exprList, PropFuncArg pfArg)
        {
            if ( pfArg.isNode() )
            {
                Node n = pfArg.getArg() ;
                Expr expr = ExprUtils.nodeToExpr(n) ;
                exprList.add(expr) ;
                return ;
            }
            
            for (  Node n : pfArg.getArgList() )
            {
                Expr expr = ExprUtils.nodeToExpr(n) ;
                exprList.add(expr) ;
            }
        }
    }

    private static Op makeStages(BasicPattern triples, Map<Triple, PropertyFunctionInstance> pfInvocations)
    {
        // Step 3 : Make the operation expression.
        //   For each property function, insert the implementation 
        //   For each block of non-property function triples, make a BGP.
        
        Op op = null; 
        BasicPattern pattern = null ;
        for ( Triple t : triples )
        {
            if ( pfInvocations.containsKey(t) )
            {
                op = flush(pattern, op) ;
                pattern = null ;
                PropertyFunctionInstance pfi = pfInvocations.get(t) ;
                OpPropFunc opPF =  new OpPropFunc(t.getPredicate(), pfi.getSubjectArgList(), pfi.getObjectArgList(), op) ;
                op = opPF ;
                continue ;
            }       
                
            // Regular triples - make sure there is a basic pattern in progress. 
            if ( pattern == null )
                pattern = new BasicPattern() ;
            pattern.add(t) ;
        }
        op = flush(pattern, op) ;
        return op ;
    }
    
    private static Op flush(BasicPattern pattern, Op op)
    {
        if ( pattern == null || pattern.isEmpty() )
        {
            if ( op == null )
                return OpTable.unit() ;
            return op ;
        }
        OpBGP opBGP = new OpBGP(pattern) ;
        return OpSequence.create(op, opBGP) ;
    }
    
    private static boolean isMagicProperty(PropertyFunctionRegistry registry, Triple pfTriple)
    {
        if ( ! pfTriple.getPredicate().isURI() ) 
            return false ;

        if ( registry.manages(pfTriple.getPredicate().getURI()) )
            return true ;
        
        return false ;
    }
    
    // Remove all triples associated with this magic property.
    // Make an instance record.
   private static PropertyFunctionInstance magicProperty(Context context,
                                                         Triple pfTriple,
                                                         BasicPattern triples)
    {
        List<Triple> listTriples = new ArrayList<>() ;

        GNode sGNode = new GNode(triples, pfTriple.getSubject()) ;
        GNode oGNode = new GNode(triples, pfTriple.getObject()) ;
        List<Node> sList = null ;
        List<Node> oList = null ;
        
        if ( GraphList.isListNode(sGNode) )
        {
            sList = GraphList.members(sGNode) ;
            GraphList.allTriples(sGNode, listTriples) ;
        }
        if ( GraphList.isListNode(oGNode) )
        {
            oList = GraphList.members(oGNode) ;
            GraphList.allTriples(oGNode, listTriples) ;
        }
        
        PropFuncArg subjArgs = new PropFuncArg(sList, pfTriple.getSubject()) ;
        PropFuncArg objArgs =  new PropFuncArg(oList, pfTriple.getObject()) ;
        
        // Confuses single arg with a list of one. 
        PropertyFunctionInstance pfi = new PropertyFunctionInstance(subjArgs, pfTriple.getPredicate(), objArgs) ;
        
        triples.getList().removeAll(listTriples) ;
        return pfi ;
    }

   
}
