/*
 * 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.core;

import java.util.* ;
import java.util.function.BiConsumer ;
import java.util.function.Consumer ;

import org.apache.jena.graph.Node ;
import org.apache.jena.sparql.ARQInternalErrorException ;
import org.apache.jena.sparql.engine.binding.Binding ;
import org.apache.jena.sparql.expr.Expr ;
import org.apache.jena.sparql.expr.ExprEvalException ;
import org.apache.jena.sparql.expr.NodeValue ;
import org.apache.jena.sparql.function.FunctionEnv ;

public class VarExprList
{
    private List<Var> vars  ;
    private LinkedHashMap<Var, Expr> exprs  ;   // Preserve order.
    
    public VarExprList(List<Var> vars)
    {
        this.vars = new ArrayList<>(vars) ;
        this.exprs = new LinkedHashMap<>() ;
    }
    
    public VarExprList(VarExprList other)
    {
        this.vars = new ArrayList<>(other.vars) ;
        this.exprs = new LinkedHashMap<>(other.exprs) ;
    }

    public VarExprList()
    {
        this.vars = new ArrayList<>() ;
        this.exprs = new LinkedHashMap<>() ;
    }
    
    public VarExprList(Var var, Expr expr)
    {
        this() ;
        add(var, expr) ;
    }

    public List<Var> getVars()          { return vars ; }
    public Map<Var, Expr> getExprs()    { return exprs ; }
    
    /** Call the action for each (variable, expression) defined.
     *  Not called when there is no expression, just a variable.
     *  Not order preserving.
     */
    public void forEachExpr(BiConsumer<Var, Expr> action) {
        exprs.forEach(action);
    }
    
    /** Call the action for each variable, in order.
     *  The expression may be null.
     *  Not called when there is no expression, just a variable.
     */
    public void forEachVarExpr(BiConsumer<Var, Expr> action) {
        //*  See {@link #forEach}    
        getVars().forEach((v) -> {
            // Maybe null.
            Expr e = exprs.get(v) ;
            action.accept(v, e);
        }) ;
    }

    /** Call the action for each variable, in order. */
    public void forEachVar(Consumer<Var> action) {
        getVars().forEach((v) -> {
            action.accept(v);
        }) ;
    }

    public boolean contains(Var var) { return vars.contains(var) ; }
    public boolean hasExpr(Var var) { return exprs.containsKey(var) ; }
    
    public Expr getExpr(Var var) { return exprs.get(var) ; }
    
    // Or Binding.get(var, NamedExprList)
    public Node get(Var var, Binding binding, FunctionEnv funcEnv)
    {
        Expr expr = exprs.get(var) ; 
        if ( expr == null )
            return binding.get(var) ; 
        
        try {
            NodeValue nv = expr.eval(binding, funcEnv) ;
            if ( nv == null )
                return null ;
            return nv.asNode() ;
        } catch (ExprEvalException ex)
        //{ Log.warn(this, "Eval failure "+expr+": "+ex.getMessage()) ; }
        { }
        return null ;
    }
    
    public void add(Var var)
    {
        // Checking here controls whether duplicate variables are allowed.
        // Duplicates with expressions are not allowed (add(Var, Expr))
        // See ARQ.allowDuplicateSelectColumns

        // Every should work either way round if this is enabled.
        // Checking is done in Query for adding result vars, and group vars.
        // if ( vars.contains(var) )
            vars.add(var) ;
    }

    public void add(Var var, Expr expr)
    {
        if ( expr == null )
        {
            add(var) ;
            return ;
        }

        if ( var == null )
            throw new ARQInternalErrorException("Attempt to add a named expression with a null variable") ;
        if ( exprs.containsKey(var) )
            throw new ARQInternalErrorException("Attempt to assign an expression again") ;
        add(var) ; 
        exprs.put(var, expr) ;
    }
    
    public void addAll(VarExprList other)
    {
        for ( Var v : other.vars )
        {
            Expr e = other.getExpr( v );
            add( v, e );
        }
    }

    public void remove(Var var) { 
        vars.remove(var) ;
        exprs.remove(var) ;
    }

    public void clear() { 
        vars.clear();
        exprs.clear();
    }
    
    public int size() { return vars.size() ; }
    public boolean isEmpty() { return vars.isEmpty() ; } 
    
    @Override
    public int hashCode()
    { 
        int x = vars.hashCode() ^ exprs.hashCode() ;
        return x ;
    }
    
    @Override
    public boolean equals(Object other)
    {
        if ( this == other) return true ;
        if ( ! ( other instanceof VarExprList ) )
            return false ;
        VarExprList x = (VarExprList)other ;
        return Objects.equals(vars, x.vars) && Objects.equals(exprs, x.exprs) ;
    }
    
    @Override
    public String toString()
    {
        return vars.toString() + " // "+exprs.toString();
    }
}
