/*******************************************************************************
 * 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.algorithms;

import java.util.Vector;

import org.eclipse.viatra2.core.IModelElement;
import org.eclipse.viatra2.core.IModelManager;
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.EdgeType;
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.operation.AllEntitiesOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.AllRelationsOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.BoundToBoundCheckOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.BoundToConstantCheckOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.ConstantToBoundCheckOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.ConstantToConstantCheckOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.CopyValueOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.ExtendBoundNodeOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.ExtendConstantNodeOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.IsEntityorRelationCheckOperation;
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.operation.VariableAssignmentCheckOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.searchgraph.ConstantSearchGraphNode;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.searchgraph.PatternCallSearchGraphNode;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.searchgraph.SearchGraphEdge;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.searchgraph.SearchGraphNode;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.searchgraph.VariableSearchGraphNode;


/**Generates the operations base on the search plan.
 * @author Akos Horvath
 *
 */
public class VPMPatternOperationGenerator {
	
	public static Vector<SearchPlanOperation> evaluateVPMOperationPlan(SearchGraphNode[] searchPlan,
			MatchingFrame template,
			IModelManager manager) throws PatternMatcherRuntimeException{
		Vector<SearchPlanOperation> searchOperations = new Vector<SearchPlanOperation>();
		SearchPlanOperation operation = null;
		
		for(SearchGraphNode node : searchPlan){
			if(node instanceof ConstantSearchGraphNode)
				node.setChecked(true);

			//tree edge evaluation
			if(node.getTreeEdge() != null && (!node.isChecked()))
				{operation = VPMPatternOperationGenerator.treeEdgeSearchOperation(node.getTreeEdge(), template,manager);
				if(operation!= null)
					{	//operation.debug();
						searchOperations.add(operation);
					}
				}
			//check operation evaluation	
			for(SearchGraphEdge edge : node.getSources()){
				if(edge.getSourceNode().isChecked() && edge.getTargetNode().isChecked())
					{operation = VPMPatternOperationGenerator.evaluateEdgeSearchPlanOperation(edge, template,manager);
						if(operation != null)
							{//operation.debug();
							searchOperations.add(operation);
							}
					}
				}
		}
		// have to check if there are any edges left
		for(SearchGraphNode node : searchPlan)
			for(SearchGraphEdge edge : node.getSources())
				if(!edge.isChecked())
					{
					//oldVersion operation = checkSearchOperation(edge, template);
					operation= VPMPatternOperationGenerator.evaluateEdgeSearchPlanOperation(edge,template,manager);
					//operation.debug();
					if(operation != null)
						searchOperations.add(operation);
					//searchOperations.add(checkSearchOperation(edge));
					}
		
		
		return searchOperations;
	}
	
	
	
	/** Returns the corresponding search plan operation equivalent to the input search graph edge
	 * @param edge The edge to process
	 * @param template the Matching frame with the bound variables
	 * @param manager Model manager of the actual model space
	 * @return the generated operation
	 */
	public static SearchPlanOperation evaluateEdgeSearchPlanOperation(
			SearchGraphEdge edge,
			MatchingFrame template,
			IModelManager manager) throws PatternMatcherRuntimeException
	{SearchPlanOperation operation = null;
		if(edge.isChecked()) return null; 
		
		//checking the type of the edge, for debugging
		if(edge.getVPMEdgeType() == EdgeType.BELOW 
				|| edge.getVPMEdgeType() == EdgeType.IN
				|| edge.getVPMEdgeType() == EdgeType.INSTANCEOF 
				|| edge.getVPMEdgeType() == EdgeType.SOURCE 
				|| edge.getVPMEdgeType() == EdgeType.TARGET
				|| edge.getVPMEdgeType() == EdgeType.SUPERTYPEOF
				|| edge.getVPMEdgeType() == EdgeType.PATTERN_CALL_PARAMETER
				|| edge.getVPMEdgeType() == EdgeType.VARIABLE_ASSIGNMENT) //TODO: new edge types has to be added to this check
			{
			operation = checkSearchOperation(edge, template,manager);
			}
		else
			{
			String[] context = {edge.getVPMEdgeType().toString(), edge.getName()};
			throw new PatternMatcherRuntimeException(PatternMatcherErrorStrings.INTERNAL_EDGETYPE_NOT_SUPPORTED
					,context
					,template.getPattern().getGTASMRepresentation(edge));
			}
		return operation;
	}
	
	
	/** Returns the corresponding search plan operation equivalent of the input search graph edge (CHECK OPERATIONS)
	 * @param edge The edge whose operation is generated
	 * @param template template the Matching frame with the bound variables
	 * @param manager model manager
	 * @return the operation itself
	 */
	private static SearchPlanOperation checkSearchOperation(
			SearchGraphEdge edge,
			MatchingFrame template,
			IModelManager manager)
	throws PatternMatcherRuntimeException{
		SearchPlanOperation operation = null;

		//some of the check operations have to be skipped as they does not represent any additional constraints
		if( edge.getSourceNode() instanceof VariableSearchGraphNode
				&& edge.getVPMEdgeType().equals(EdgeType.BELOW)	//default Scope value
				&& (template.getValue(((VariableSearchGraphNode)edge.getSourceNode()).getId()) != null)			//default Scope value
				&& ((IModelElement)template.getValue(((VariableSearchGraphNode)edge.getSourceNode()).getId())).equals(manager.getRoot()))
			{	
			edge.setChecked(true);
			return null;
			}
		
		// in case the source is an entity or a relation a special check operation is required
		if(	edge.getSourceNode() instanceof ConstantSearchGraphNode
				&& edge.getVPMEdgeType().equals(EdgeType.INSTANCEOF)
				&& ( ((ConstantSearchGraphNode)edge.getSourceNode()).getElement().equals(ISearchGraph.VPM_RELATION_FQN) 
						|| ((ConstantSearchGraphNode)edge.getSourceNode()).getElement().equals(ISearchGraph.VPM_ENTITY_FQN) ))
			{
			//TODO: Can an entity have an instance relation to an entity?
			//If yes, then can be tricked out as an entity can have an instance relation to a relation and it is not checked
			operation = new IsEntityorRelationCheckOperation(((VariableSearchGraphNode)edge.getTargetNode()).getId()
					,edge,
					((ConstantSearchGraphNode)edge.getSourceNode()).getElement());
			edge.setChecked(true);
			return operation;
			}	
		/************complex operations******************/
		//pattern call operation
		if(edge.getTargetNode() instanceof PatternCallSearchGraphNode)
				{
				String[] context = {edge.getTargetNode().getName()};
				throw new PatternMatcherRuntimeException(
						PatternMatcherErrorStrings.INTERNAL_PATTERNCALLNODE_EXCEPTION
						,context
						,template.getPattern().getGTASMRepresentation(edge));
				}
				
		
		/**************simple operations*******************/
		if(edge.getVPMEdgeType().equals(EdgeType.VARIABLE_ASSIGNMENT))
			operation = new VariableAssignmentCheckOperation(((VariableSearchGraphNode)edge.getSourceNode()).getId(),
					((VariableSearchGraphNode)edge.getTargetNode()).getId()
					,edge); //TODO: does the direction counts? (inverse or not)
		else
		if(edge.getSourceNode() instanceof VariableSearchGraphNode && edge.getTargetNode() instanceof VariableSearchGraphNode)
			operation = new BoundToBoundCheckOperation(((VariableSearchGraphNode)edge.getSourceNode()).getId()
						,((VariableSearchGraphNode)edge.getTargetNode()).getId()
						,edge);
		else
		if(edge.getSourceNode() instanceof VariableSearchGraphNode && edge.getTargetNode() instanceof ConstantSearchGraphNode )
			operation = new BoundToConstantCheckOperation(((VariableSearchGraphNode)edge.getSourceNode()).getId()
					,manager.getElementByName(((ConstantSearchGraphNode)edge.getTargetNode()).getElement())
					,edge);
		else
		if(edge.getSourceNode() instanceof ConstantSearchGraphNode && edge.getTargetNode() instanceof VariableSearchGraphNode)
			operation = new ConstantToBoundCheckOperation(manager.getElementByName(((ConstantSearchGraphNode)edge.getSourceNode()).getElement())
					,((VariableSearchGraphNode)edge.getTargetNode()).getId()
					,edge);
		else
		if(edge.getSourceNode() instanceof ConstantSearchGraphNode && edge.getTargetNode() instanceof ConstantSearchGraphNode)
			operation = new ConstantToConstantCheckOperation(manager.getElementByName(((ConstantSearchGraphNode)edge.getSourceNode()).getElement())
					,manager.getElementByName(((ConstantSearchGraphNode)edge.getTargetNode()).getElement())
					,edge);
		
		if(operation != null)
			edge.setChecked(true);
		
		return operation;
		
	}
	
	private static int getPatternCallParameterId(Integer id,
			PatternCallSearchGraphNode callNode, MatchingFrame frame
			) throws PatternMatcherRuntimeException {
		Integer[] inputParameterMapping = callNode.getInputParameterMapping();
		
		for(int i =0; i< inputParameterMapping.length; i++)
			if(id == inputParameterMapping[i])
				return i;
		
		String[] context = {callNode.getName()};
		throw new PatternMatcherRuntimeException(
				PatternMatcherErrorStrings.INTERNAL_PATTERNCALLNODE_WRONGPARAMETER_ORDER
				,context
				,frame.getPattern().getGTASMRepresentation(callNode));
	}

	/** Returns the corresponding search plan operation equivalent of the input search graph TREE edge (EXTEND OPERATIONS)
	 * @param edge 
	 * @param Matchingframe containing the bound variables
	 * @param manager model manager
	 * @return
	 */
	public static SearchPlanOperation treeEdgeSearchOperation(SearchGraphEdge edge, MatchingFrame template, IModelManager manager) throws PatternMatcherRuntimeException{
		SearchPlanOperation operation = null;
		if(edge.getSourceNode().isChecked() && edge.getTargetNode().isChecked())
			//the source and the target are already checked, simple checks the edge
			operation = checkSearchOperation(edge, template,manager);
		else//not a check type operation

		/**********complex operations**********/
		if(edge.getVPMEdgeType().equals(EdgeType.PATTERN_CALL_PARAMETER)
				|| edge.getVPMEdgeType().equals(EdgeType.PATTERN_CALL_STORAGE))
		{
			if(edge.isSource()) //the edge is the tree edge of the pattern call node
			{
				PatternCallSearchGraphNode callNode = (PatternCallSearchGraphNode) edge.getTargetNode();
				Boolean[] boundParameters = new Boolean[callNode.getPatternNode().getPattern().getSymParameters().size()];
				
					for (SearchGraphEdge callEdge:callNode.getSources())
					{
						//[DEBUG] error in the algorithm, one edge of the PatternCall node is already checked
						//if(!callEdge.isChecked())
						//	System.out.println("[ERROR] One edge of a PatternCallNode is already traversed before the PatternNode was traversed");

						//if it is a bound input parameter
						if(callEdge.getVPMEdgeType().equals(EdgeType.PATTERN_CALL_PARAMETER))
						{	if(callEdge.getSourceNode().isChecked())
								{
								boundParameters[getPatternCallParameterId(((VariableSearchGraphNode)callEdge.getSourceNode()).getId()
																		,callNode,template)] = true;
								}
							else//the pattern call will bound the variable
							{	if(callEdge.getSourceNode().getTreeEdge().getSourceNode().equals(callNode))
									{
									boundParameters[getPatternCallParameterId(((VariableSearchGraphNode)callEdge.getSourceNode()).getId()
											,callNode,template)] = false;
									callEdge.getSourceNode().setChecked(true);
									}
								else//Error the recursive call is not the tree edge for an unbound parameter
									{
									String[] context = {callEdge.getSourceNode().getName(),callNode.getName()};
									throw new PatternMatcherRuntimeException(
											PatternMatcherErrorStrings.INTERNAL_PATTERNCALLNODE_EDGE_EXCEPTION
											,context
											,template.getPattern().getGTASMRepresentation(callNode));
									}
							}
						}
						//else // it is an incrementally matched pattern call -> not part of the invocation context

						callEdge.setChecked(true);
					}
					return //PatternCallOperation patternOperation =
						new PatternCallOperation(callNode.getPatternNode()
							,callNode.getInputParameterMapping(),boundParameters);
				
			}
			else//the edge is an outgoing edge from a pattern call node
			{
				//edge.getTargetNode().setChecked(true);
				PatternCallSearchGraphNode callNode = (PatternCallSearchGraphNode) edge.getSourceNode();
				String[] context = {edge.getName(),callNode.getName()};
				throw new PatternMatcherRuntimeException(
						PatternMatcherErrorStrings.INTERNAL_PATTERNCALLNODE_EDGE_TRAVERSAL_EXCEPTION
						,context
						,template.getPattern().getGTASMRepresentation(callNode));
			}
		}
		/**************simple operations	******************/
		else	
		if(edge.getSourceNode().isChecked())
				{
				//simple operation
				if(edge.getVPMEdgeType().equals(EdgeType.VARIABLE_ASSIGNMENT))
					{operation = new CopyValueOperation(((VariableSearchGraphNode)edge.getSourceNode()).getId()
							,((VariableSearchGraphNode)edge.getTargetNode()).getId()
							,edge);
					}
				else
				if(edge.getSourceNode() instanceof ConstantSearchGraphNode &&
						((ConstantSearchGraphNode)edge.getSourceNode()).getElement().equals(ISearchGraph.VPM_ENTITY_FQN))	
					{
					operation = new AllEntitiesOperation(((VariableSearchGraphNode)edge.getTargetNode()).getId()
							,edge, manager);
					}
				else
				if(edge.getSourceNode() instanceof ConstantSearchGraphNode &&
							((ConstantSearchGraphNode)edge.getSourceNode()).getElement().equals(ISearchGraph.VPM_RELATION_FQN))	
						{
						operation = new AllRelationsOperation(((VariableSearchGraphNode)edge.getTargetNode()).getId()
								,edge, manager);
						}
				else
				if(edge.getSourceNode() instanceof VariableSearchGraphNode && edge.getTargetNode() instanceof VariableSearchGraphNode)
					{operation = new ExtendBoundNodeOperation(((VariableSearchGraphNode)edge.getSourceNode()).getId()
							,((VariableSearchGraphNode)edge.getTargetNode()).getId()
							,edge);
					}
				else
					if(edge.getSourceNode() instanceof ConstantSearchGraphNode && edge.getTargetNode() instanceof VariableSearchGraphNode)
					{operation = new ExtendConstantNodeOperation(manager.getElementByName(((ConstantSearchGraphNode)edge.getSourceNode()).getElement())
							,((VariableSearchGraphNode)edge.getTargetNode()).getId()
							,edge);
					}	
				}
		else
		if(edge.getTargetNode().isChecked())
			{
			//simple operation
			if(edge.getVPMEdgeType().equals(EdgeType.VARIABLE_ASSIGNMENT))
			{operation = new CopyValueOperation(((VariableSearchGraphNode)edge.getTargetNode()).getId()
					,((VariableSearchGraphNode)edge.getSourceNode()).getId()
					,edge);
				}
			if(edge.getTargetNode() instanceof ConstantSearchGraphNode &&
					((ConstantSearchGraphNode)edge.getTargetNode()).getElement().equals(ISearchGraph.VPM_ENTITY_FQN))	
				{
				operation = new AllEntitiesOperation(((VariableSearchGraphNode)edge.getSourceNode()).getId()
						,edge, manager);
				}
			else
			if(edge.getTargetNode() instanceof ConstantSearchGraphNode &&
						((ConstantSearchGraphNode)edge.getTargetNode()).getElement().equals(ISearchGraph.VPM_RELATION_FQN))	
					{
					operation = new AllRelationsOperation(((VariableSearchGraphNode)edge.getSourceNode()).getId()
							,edge, manager);
					}
			else
			if(edge.getSourceNode() instanceof VariableSearchGraphNode && edge.getTargetNode() instanceof VariableSearchGraphNode)
				{operation = new ExtendBoundNodeOperation(((VariableSearchGraphNode)edge.getTargetNode()).getId()
						,((VariableSearchGraphNode)edge.getSourceNode()).getId()
						,edge);
				}
			else
			if(edge.getSourceNode() instanceof ConstantSearchGraphNode && edge.getTargetNode() instanceof VariableSearchGraphNode)
				{operation = new ExtendConstantNodeOperation(manager.getElementByName(((ConstantSearchGraphNode)edge.getTargetNode()).getElement())
						,((VariableSearchGraphNode)edge.getSourceNode()).getId()
						,edge);
				}	
			}
		
		if(operation != null)
			{
			edge.getSourceNode().setChecked(true);
			edge.getTargetNode().setChecked(true);
			edge.setChecked(true);
			}
		
		return operation;
		
	}

}
