/*******************************************************************************
 * Copyright (c) 2004-2008 Akos Horvath, Gergely Varro and Daniel Varro
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Akos Horvath, Gergely Varro - initial API and implementation
 *******************************************************************************/

 package org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.callgraph;

import org.eclipse.viatra2.core.IModelManager;
import org.eclipse.viatra2.gtasm.patternmatcher.PatternCallSignature;
import org.eclipse.viatra2.gtasm.patternmatcher.exceptions.PatternMatcherCompileTimeException;
import org.eclipse.viatra2.gtasm.patternmatcher.exceptions.PatternMatcherRuntimeException;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.MatchingFrame;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.PatternMatcherErrorStrings;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.SearchPlan;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.SearchPlanKey;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.VariableID;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.algorithms.ISearchGraph;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.algorithms.SearchGraphFactory;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.DummyOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.InjectivityCheckOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.PatternCallOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.SearchPlanOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.rgg.IQueueContentProvider;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.rgg.IndexedRule;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.rgg.LocalGoal;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.rgg.MagicSet;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.rgg.RemoteGoal;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.rgg.UnindexedRule;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.searchgraph.AbstractNode;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.term.ITermHandler;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.core.AnnotatedElement;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.core.GTASMElement;
import org.eclipse.viatra2.logger.Logger;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;


/**
 * A FlattenedPattern corresponds to a PatternBody, in which
 * variables from all the embedded pattern invocations are aggregated.
 * 
 * FlattenedPatterns are generated during the pattern invocation analysis of
 * GTPatternBodies. If the pattern call graph is a DAG, then we have a 
 * non-recursive FlattenedPattern consisting of all the variables that appear
 * in the GTPatternBody itself or any patterns that are called by the 
 * GTPatternBody.
 * 
 * Each branch of OR patterns obviously generate a new FlattenedPattern.
 * 
 * The interpreted engine uses the following mapping:
 * VariableType => PatternVariable
 */
public class FlattenedPattern extends EvenLevelNode 
	implements Comparable<FlattenedPattern> {
    
    private boolean isRecursionBased;

    private ISearchGraph searchGraph;
	/**
     * The mapping of pattern variables to their location in
     * the PatternFrames.
	 */
    private Map<VariableID,Integer> variableMapping;
    private Map<Integer, Set<VariableID>> inverseVariableMapping;

    private Set<Pair> injectivityExclusionSet, injectivityInclusionSet;
    
	/**
     * The mapping of PatternSignatures to the SearchPlans
     * that are available for a given PatternSignature.
	 */
	private Map<SearchPlanKey,Collection<SearchPlan>> searchPlanMapping;

	private Vector<SearchPlanOperation> preSearchPlanOperations;
    private Vector<SearchPlanOperation> postSearchPlanOperations;
    
    /**
     * The size of the binding arrays inside the corresponding 
     * MatchingFrames.
	 */
	private int frameSize;
    private int injectivityFrameSize;
    
    public FlattenedPattern(PatternNode parent, List<IFlattenedPatternElement> specification) 
        throws PatternMatcherCompileTimeException {
    	super(parent);
    	//this.SearchGraph = new VPMBasedSearchGraph(parent.getModelManager());
    	this.searchGraph = SearchGraphFactory.getSearchGraph(parent.getModelManager());
    	this.variableMapping = new HashMap<VariableID, Integer>();
        this.inverseVariableMapping = new TreeMap<Integer, Set<VariableID>>();
    	this.searchPlanMapping = new HashMap<SearchPlanKey, Collection<SearchPlan>>();
      	this.preSearchPlanOperations = new Vector<SearchPlanOperation>();
        this.postSearchPlanOperations = new Vector<SearchPlanOperation>();
        this.isRecursionBased = false;
        this.frameSize = 0;
        this.injectivityFrameSize = 0;
        this.injectivityExclusionSet = new HashSet<Pair>();
        injectivityInclusionSet = new HashSet<Pair>();

        Logger logger = parent.getLogger();
        // Main loop for processing all the variables of a pattern variant
        for (int i = 0; i < specification.size(); i++) {
            IFlattenedPatternElement element = specification.get(i);
            element.setCurrentLocation(i);
            element.addFormalParameters(this);
            element.addLocalVariables(this);
        }
        injectivityFrameSize = frameSize;
        for (int i = 0; i < specification.size(); i++) {
            IFlattenedPatternElement element = specification.get(i);
            element.processNegativeApplicationConditions(this, logger, parent.getModelManager());
            element.processCheckExpressions(this, logger);
            element.buildSearchGraph(this);
            element.generateElementInjectivityConstraints(this, 
            		element.processVariableAssignments(this),
            		element.processInjectivityAssignments(this));
            
            // element.processFormalParameterScopes(this);
            //Scope of the input parameter is not added to the search graph
            // element.processPatternCallScopes(this);
        }
        this.searchGraph.connectDanglingRelations(this);
        addPostSearchPlanOperation(new InjectivityCheckOperation());

        //TODO: in case of adaptive pattern matching the searchNodeOrder is not fix have to go back to the iSearchGraph itself
        // the order of the nodes are calculated, it would be better to have it contained

        //For debugging purpose
//      result.searchNodeOrder= result.alg.evaulateSearchPlan(result);
//      result.debug(); 
//      //result.debugPL(a);
//      result.alg.evaulateOperationPlan(result.searchNodeOrder);

        printVariableMapping(logger);
    }
    
    /**
     * Adds SearchPlan plan to the set of search plans with
     * PatternSignature signature.
     * @param signature The key that identifies the set of search plans 
     * to which plan has to be added. 
     * @param plan The search plan to be added.
     * @return true if plan has been successfully added to the
     * search plan mapping dictionary.
     */
    boolean addSearchPlan(PatternCallSignature signature, SearchPlan plan) {
        return false;
    }
    
    MatchingFrame getInstance() {
        return null;
    }
    
    Collection<SearchPlan> getSearchPlansFor(SearchPlanKey key) {
        return searchPlanMapping.get(key);
    }

    /**
     * 
     * @return the frameSize
     */
    public int getFrameSize() {
        return frameSize;
    }

    /**
     * @param frameSize the frameSize to set
     */
    public void setFrameSize(int frameSize) {
        this.frameSize = frameSize;
    }
    
    public ISearchGraph getSearchGraph() {
    	return searchGraph;
    }
    
    public void addPreSearchPlanOperation(SearchPlanOperation operation) {
        preSearchPlanOperations.add(operation);
    }
    
    public void addPostSearchPlanOperation(SearchPlanOperation operation) {
        postSearchPlanOperations.add(operation);
    }
    
    public Integer getIndex(VariableID variable) {
        return variableMapping.get(variable);
    }
    
    public Set<VariableID> getVariableIDs(Integer index) {
        return inverseVariableMapping.get(index);
    }
    
    private void addToInverseMapping(VariableID variable, Integer index) {
        Set<VariableID> idSet = inverseVariableMapping.get(index);
        if (idSet == null) {
            idSet = new HashSet<VariableID>();
            inverseVariableMapping.put(index, idSet);
        }
        idSet.add(variable);
    }
    
    public void setIndex(VariableID variable, Integer index) {
        variableMapping.put(variable, index);
        addToInverseMapping(variable, index);
    }
    
    public int addVariable(VariableID variable) {
        if (variable != null) {
            variableMapping.put(variable, frameSize);
            addToInverseMapping(variable, frameSize);
        }
        return frameSize++;
    }
    
    private void printVariableMapping(Logger logger) {
        for (VariableID id : variableMapping.keySet()) {
            logger.debug(id.toString() + " : " + variableMapping.get(id));
        }
        for (Integer key : inverseVariableMapping.keySet()) {
            for (VariableID id : inverseVariableMapping.get(key)) {
                logger.debug(key + " : " + id.toString());
            }
        }
        logger.debug("Injective frame size: \t" + injectivityFrameSize);
        logger.debug("Frame size: \t" + frameSize);
    }
    
    public boolean containsIndex(VariableID variable){
    	return variableMapping.containsKey(variable);
    }

	// Moves non-recursion based patterns ahead of recursion based patterns
    public int compareTo(FlattenedPattern o) {
        /*
         * this = o : !isRecursionBased AND !o.isRecursionBased
         * this = o : isRecursionBased AND o.isRecursionBased
         * this > o : isRecursionBased AND !o.isRecursionBased
         * this < o : !isRecursionBased AND o.isRecursionBased
         */
        if (isRecursionBased == o.isRecursionBased) {
            return 0;
        } else {
            return (isRecursionBased ? 1 : -1);
        }
    }

    /**
     * @return the injectivityFrameSize
     */
    public int getInjectivityFrameSize() {
        return injectivityFrameSize;
    }

    public ITermHandler getTermHandler() {
        return parent.getTermHandler();
    }
    
    public Collection<SearchPlanOperation> generateCoreSearchPlan(Boolean[] adornment, IModelManager manager) throws PatternMatcherRuntimeException{
    	return searchGraph.generateSearchPlan(this, adornment, manager);
    }
    
    public List<SearchPlanOperation> generateSearchPlan(Boolean[] adornment, IModelManager manager) throws PatternMatcherRuntimeException{
    	Collection<SearchPlanOperation> vec = searchGraph.generateSearchPlan(this, adornment,manager);

    	// Copies pre and post operations
    	ArrayList<SearchPlanOperation> finalSearchPlan = new ArrayList<SearchPlanOperation>();
    	finalSearchPlan.addAll(preSearchPlanOperations);
    	finalSearchPlan.addAll(vec);
    	finalSearchPlan.addAll(postSearchPlanOperations);
    	SearchPlanOperation[] operations = new SearchPlanOperation[finalSearchPlan.size()];
    	operations = finalSearchPlan.toArray(operations);
    	SearchPlan splan = new SearchPlan(operations);
    	splan.printDebugInformation(parent.getLogger());
    	// sets the iSearchGraph back to starting state
    	searchGraph.initSearchGraph();
    	
        return finalSearchPlan;
    }

    IQueueContentProvider buildSubtree(Map<String, RemoteGoal> rggRoots,
    		MagicSet ms,
    		List<SearchPlanOperation> searchPlan, 
    		int upperBound, 
    		SortedSet<Integer> preCallInterfaceVariables) throws PatternMatcherRuntimeException {
    	//gervarro: put to the constructor of the Rule?
        SortedSet<Integer> localVariables = new TreeSet<Integer>();
        int i = upperBound;
    	for (; i >= 0 && !(searchPlan.get(i) instanceof PatternCallOperation); i--) {
			searchPlan.get(i).calculateSidewaysPassedVariables(preCallInterfaceVariables);
			searchPlan.get(i).calculateLocalVariables(localVariables);
    	}

    	if (upperBound < 0) {
    		// sup_i.0 :- ms_i
    		return ms; // look up the appropriate magic set
    	} else if (i < upperBound) {
    		// sup_i.j :- sup_i.(j-1), local_j
    		IQueueContentProvider left = 
    			buildSubtree(rggRoots, ms, searchPlan, i, preCallInterfaceVariables);
    		List<SearchPlanOperation> operations = 
    			new Vector<SearchPlanOperation>(searchPlan.subList(i+1, upperBound+1));
    		operations.add(new DummyOperation());
    		SearchPlanOperation[] array = new SearchPlanOperation[operations.size()];
    		array = operations.toArray(array);
    		LocalGoal right = new LocalGoal(array);

    		/*
			int size = localVariables.size();
			Integer[] localVariableMapping = new Integer[size];
			Boolean[] adornment = new Boolean[size];
			int counter = 0;
			for (Integer position: localVariables) {
				adornment[counter] = preCallInterfaceVariables.contains(position);
				counter++;
			}
			localVariables.toArray(localVariableMapping);
			*/

    		return new UnindexedRule(this, left, right);
    	} else if (i == upperBound) {
    		// sup_i.j :- sup_i.(j-1), remote_j
    		PatternCallOperation pco = (PatternCallOperation) searchPlan.get(i);
    		pco.calculateSidewaysPassedVariables(preCallInterfaceVariables);
			pco.calculateLocalVariables(localVariables);
			
    		IQueueContentProvider left = 
    			buildSubtree(rggRoots, ms, searchPlan, i-1, preCallInterfaceVariables);

    		String id = RemoteGoal.generateID(pco.getPatternNode(), pco.getAdornment());
    		// If right goal exists in runtimes
     		if (rggRoots.containsKey(id)) {
        		// then get the runtime from runtimes
    			RemoteGoal right = rggRoots.get(id);
    			return new IndexedRule(this, left, right, pco.getParameterMapping(), pco.getAdornment());
    		} else {
        		// else generate a new runtime
    			RemoteGoal right = pco.getPatternNode().buildRuleGoalGraph(pco.getAdornment(),rggRoots);
    			return new IndexedRule(this, left, right, pco.getParameterMapping(), pco.getAdornment());
    		}
    		// ms_call :- sup_i.(j-1)
     		// Explicitly handled by RemoteGoal 
    	} else {
    		String[] context = {getParent().getPattern().getName()};
    		throw new PatternMatcherRuntimeException(
    				PatternMatcherErrorStrings.INTERNAL_FLATTENED_PATTERN_BUILD
    				,context
    				,getParent().getPattern());
    	}
    }
    
    public AnnotatedElement getGTASMRepresentation(AbstractNode node){
    	return searchGraph.getGTASMRepresentation(node);
    }
    
    
    
    
    public Pair addInjectivityExclusionPair(int left, int right) {
    	Pair p = (left < right ? new Pair(left,right) : new Pair(right,left));
    	injectivityExclusionSet.add(p);
    	return p;
    }
    
    public void removeInjectivityExclusionPair(int left, int right) {
    	Pair p = (left < right ? new Pair(left,right) : new Pair(right,left));
    	injectivityExclusionSet.remove(p);
    }
    
    public Pair addInjectivityInclusionPair(int left, int right) {
     	Pair p = (left < right ? new Pair(left,right) : new Pair(right,left));
    	injectivityInclusionSet.add(p);
    	return p;
 	}
    
    public void removeInjectivityInclusionPair(int left, int right) {
     	Pair p = (left < right ? new Pair(left,right) : new Pair(right,left));
    	injectivityInclusionSet.remove(p);
 		
	}
    
    public boolean isIncludedInInjectivityCheck(int i, int j) {
    	Pair p = (i < j ? new Pair(i,j) : new Pair(j,i));
    	return injectivityInclusionSet.contains(p); // if it is in the Inclusion set then it has to be checked for injectivity (|| !injectivityExclusionSet.contains(p)) 
    }
    
	public static class Pair {
		public Integer getLeft() {
			return left;
		}

		public Integer getRight() {
			return right;
		}

		private Integer left;
		private Integer right;
		
		Pair(int left, int right) {
			this.left = left;
			this.right = right;
		}
		
		public boolean equals(Object other) {
			if (other != null && other instanceof Pair) {
				Pair o = (Pair) other;
				return (left == o.left && right == o.right);
			} else {
				return false;
			}
		}
		
		public int hashCode() {
			return left.hashCode() + right.hashCode();
		}
	}

	

	
}
