/**
 * Copyright (c) 2010, 2011 Mia-Software.
 * 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:
 *    Gabriel Barbier (Mia-Software) - initial API and implementation
 *    Fabien Giquel (Mia-Software) - Bug 339720 : MoDisco Discoverers (infra + techno) API clean
 *    Nicolas Bros (Mia-Software) - Bug 335003 - [Discoverer] : Existing Discoverers Refactoring based on new framework
 *******************************************************************************/

package org.eclipse.modisco.usecase.modelfilter.methodcalls.discoverer.internal.converter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.gmt.modisco.java.AbstractMethodDeclaration;
import org.eclipse.gmt.modisco.java.AbstractMethodInvocation;
import org.eclipse.gmt.modisco.java.Assignment;
import org.eclipse.gmt.modisco.java.Block;
import org.eclipse.gmt.modisco.java.BodyDeclaration;
import org.eclipse.gmt.modisco.java.ClassDeclaration;
import org.eclipse.gmt.modisco.java.ClassInstanceCreation;
import org.eclipse.gmt.modisco.java.Expression;
import org.eclipse.gmt.modisco.java.MethodInvocation;
import org.eclipse.gmt.modisco.java.SingleVariableAccess;
import org.eclipse.gmt.modisco.java.TypeAccess;
import org.eclipse.gmt.modisco.java.TypeDeclaration;
import org.eclipse.gmt.modisco.java.VariableDeclaration;
import org.eclipse.modisco.usecase.modelfilter.methodcalls.methodcalls.CallNode;
import org.eclipse.modisco.usecase.modelfilter.methodcalls.methodcalls.CallsModel;
import org.eclipse.modisco.usecase.modelfilter.methodcalls.methodcalls.MethodCall;
import org.eclipse.modisco.usecase.modelfilter.methodcalls.methodcalls.MethodcallsFactory;

/**
 * From a java model, we will extract method calls informations to initialise a
 * method calls model.
 */
public class MethodCallsGraphConverter {

	private final MethodcallsFactory factory = MethodcallsFactory.eINSTANCE;
	private final Map<AbstractMethodDeclaration, CallNode> javaOperationToCallNode = new HashMap<AbstractMethodDeclaration, CallNode>();
	private final List<AbstractMethodInvocation> allInvocations = new ArrayList<AbstractMethodInvocation>();
	private final List<TypeDeclaration> allTypes = new ArrayList<TypeDeclaration>();

	/**
	 * From a java resource, we will compute method calls graph then initialize
	 * a method calls model.
	 *
	 * @param javaResource
	 * @return corresponding method calls model
	 */
	public CallsModel convertJavaResourceToMethodCallsModel(
			final Resource javaResource, final String targetModelName) {
		/*
		 * Create method calls model root
		 */
		CallsModel callsModel = this.factory.createCallsModel();
		callsModel.setName(targetModelName);

		List<AbstractMethodDeclaration> allOperations = getAllOperations(javaResource);
		/*
		 * iterate over all operations to initialize call nodes
		 */
		for (AbstractMethodDeclaration javaOperation : allOperations) {
			/*
			 * create calls node
			 */
			CallNode callNode = this.factory.createCallNode();
			callNode.setJavaMethod(javaOperation);
			callsModel.getCallNodes().add(callNode);
			if (javaOperation.getUsages().isEmpty()) {
				callsModel.getRootNodes().add(callNode);
			}
			// init also convenient hashmap ...
			this.javaOperationToCallNode.put(javaOperation, callNode);
		}
		/*
		 * iterate over all operations to compute method calls informations
		 */
		for (AbstractMethodDeclaration javaOperation : allOperations) {
			CallNode callNode = this.javaOperationToCallNode.get(javaOperation);
			List<AbstractMethodInvocation> calledMethods = getCalledMethods(javaOperation);
			/*
			 * Compute call node name
			 */
			String parentName = ""; //$NON-NLS-1$
			if (javaOperation.getAbstractTypeDeclaration() != null) {
				parentName = javaOperation.getAbstractTypeDeclaration()
						.getName();
			}
			String name = parentName + " :: " + javaOperation.getName(); //$NON-NLS-1$
			if (!calledMethods.isEmpty()) {
				name = name + " (" + calledMethods.size() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
			}
			callNode.setName(name);
			/*
			 * initialize method call elements
			 */
			for (int index = 0; index < calledMethods.size(); index++) {
				MethodCall methodCall = this.factory.createMethodCall();
				methodCall.setOrder(index);
				CallNode callee = this.javaOperationToCallNode
						.get(calledMethods.get(index).getMethod());
				methodCall.setCallee(callee);
				/*
				 * compute filtered methods 1. we have to retrieve variable
				 * declaration which contains this method invocation, if it
				 * exists. 2. get collection of filtered potential types
				 */
				VariableDeclaration variableDeclaration = getVariableDeclaration(calledMethods
						.get(index));
				if (variableDeclaration != null) {
					for (TypeDeclaration subtype : getFilteredPotentialTypes(variableDeclaration)) {
						/*
						 * we have to retrieve corresponding method same name,
						 * same number of parameters same name of parameters ?
						 * -> may change same type of parameters ? may be a
						 * subtype
						 */
						for (BodyDeclaration body : subtype
								.getBodyDeclarations()) {
							if (body instanceof AbstractMethodDeclaration) {
								AbstractMethodDeclaration subMethod = (AbstractMethodDeclaration) body;
								if (javaOperation.getName().equals(
										body.getName())) {
									if (javaOperation.getParameters().size() == subMethod
											.getParameters().size()) {
										CallNode subNode = this.javaOperationToCallNode
												.get(subMethod);
										methodCall.getFilteredSubMethods().add(
												subNode);
									}
								}
							}
						}
					}
				}
				/*
				 * if everything is ok, we could add this method call to current
				 * call node element.
				 */
				callNode.getMethodCalls().add(methodCall);
			}
			/*
			 * initialize collection of sub methods
			 */
			TypeDeclaration parentType = getTypeDeclaration(javaOperation);
			for (TypeDeclaration subtype : getAllSubTypes(parentType)) {
				/*
				 * we have to retrieve corresponding method same name, same
				 * number of parameters same name of parameters ? -> may change
				 * same type of parameters ? may be a subtype
				 */
				for (BodyDeclaration body : subtype.getBodyDeclarations()) {
					if (body instanceof AbstractMethodDeclaration) {
						AbstractMethodDeclaration subMethod = (AbstractMethodDeclaration) body;
						if (javaOperation.getName().equals(body.getName())) {
							if (javaOperation.getParameters().size() == subMethod
									.getParameters().size()) {
								CallNode subNode = this.javaOperationToCallNode
										.get(subMethod);
								callNode.getSubMethods().add(subNode);
							}
						}
					}
				}
			}
		}
		return callsModel;
	}

	/**
	 * To retrieve all method declarations from java model.
	 *
	 * We will also initialize collections of types and method invocations to
	 * iterate only once on all java elements.
	 *
	 * @param javaResource
	 * @return
	 */
	private final List<AbstractMethodDeclaration> getAllOperations(
			final Resource javaResource) {
		List<AbstractMethodDeclaration> result = new ArrayList<AbstractMethodDeclaration>();
		TreeIterator<EObject> iterator = javaResource.getAllContents();
		while (iterator.hasNext()) {
			EObject object = iterator.next();
			if (object instanceof AbstractMethodDeclaration) {
				AbstractMethodDeclaration operation = (AbstractMethodDeclaration) object;
				result.add(operation);
			} else if (object instanceof AbstractMethodInvocation) {
				AbstractMethodInvocation invocation = (AbstractMethodInvocation) object;
				this.allInvocations.add(invocation);
			} else if (object instanceof TypeDeclaration) {
				TypeDeclaration currentClassDeclaration = (TypeDeclaration) object;
				this.allTypes.add(currentClassDeclaration);
			}
		}
		return result;
	}

	/**
	 * If we want to get all the called methods from this method declaration, we
	 * have to select all usages which are contained by this method declaration.
	 * It means all instances of AbstractMethodInvocation Yet, we have also to
	 * sort this collection by its order in call sequence
	 *
	 * @param parent
	 * @return
	 */
	private final List<AbstractMethodInvocation> getCalledMethods(
			final AbstractMethodDeclaration parent) {
		List<AbstractMethodInvocation> invocations = getInvocations(parent);
		// sort invocations ...
		Collections.sort(invocations, new MethodInvocationComparator());
		return invocations;
	}

	/**
	 * To retrieve all method invocations that are contained by this method
	 * declaration element.
	 *
	 * @param parent
	 * @return
	 */
	private final List<AbstractMethodInvocation> getInvocations(
			final AbstractMethodDeclaration parent) {
		List<AbstractMethodInvocation> invocations = new ArrayList<AbstractMethodInvocation>();
		for (AbstractMethodInvocation invocation : this.allInvocations) {
			if (parent == getInvoker(invocation)) {
				invocations.add(invocation);
			}
		}
		return invocations;
	}

	/**
	 * To retrieve the method declaration element which contains the source
	 * method invocation. Type of parameter element is EObject, because we have
	 * to navigate into statements hierarchy which many different kinds of
	 * elements
	 *
	 * @param element
	 * @return
	 */
	private final AbstractMethodDeclaration getInvoker(final EObject element) {
		AbstractMethodDeclaration result = null;
		if (element != null) {
			if (element instanceof AbstractMethodDeclaration) {
				result = (AbstractMethodDeclaration) element;
			} else {
				result = getInvoker(element.eContainer());
			}
		}
		return result;
	}

	protected static class MethodInvocationComparator implements
			Comparator<AbstractMethodInvocation> {

		public int compare(final AbstractMethodInvocation invocation1,
				final AbstractMethodInvocation invocation2) {
			int result = -1;
			/*
			 * Initially, I used location in file to sort invocations, but
			 * needed information is no longer retained in java model ...
			 *
			 * Perhaps could I use index of parent element which is directly
			 * contained in block statement of the declaring method ?
			 */
			Block rootBlock1 = getRootBlock(invocation1);
			Block rootBlock2 = getRootBlock(invocation2);
			if ((rootBlock1 == null) || (rootBlock2 == null)) {
				result = 0;
			} else {
				int index1 = computeIndex(invocation1, rootBlock1);
				int index2 = computeIndex(invocation2, rootBlock2);
				/*
				 * specific case: both invocations have the same index and are
				 * contained in the same block.
				 *
				 * So we have to retrieve first common parent block and use it
				 * to compute index ...
				 */
				if ((index1 == index2) && (rootBlock1 == rootBlock2)) {
					Block commonBlock = getFirstCommonParentBlock(invocation1,
							invocation2, rootBlock1);
					index1 = computeIndex(invocation1, commonBlock);
					index2 = computeIndex(invocation2, commonBlock);
				}

				result = Integer.valueOf(index1).compareTo(
						Integer.valueOf(index2));
			}
			return result;
		}

		private static final int INVALID_INDEX = -2;
		private final int computeIndex(final EObject element,
				final Block rootBlock) {
			int result = MethodCallsGraphConverter.MethodInvocationComparator.INVALID_INDEX;
			if (element.eContainer() == rootBlock) {
				result = rootBlock.getStatements().indexOf(element);
			} else {
				result = computeIndex(element.eContainer(), rootBlock);
			}
			return result;
		}

		private final Block getRootBlock(final EObject element) {
			Block result = null;
			if (element != null) {
				if (element instanceof AbstractMethodDeclaration) {
					result = ((AbstractMethodDeclaration) element).getBody();
				} else {
					result = getRootBlock(element.eContainer());
				}
			}
			return result;
		}

		/*
		 * To retrieve the first common parent block of two elements lets start
		 * from an example: block A contains another block B (with other
		 * statements) block B contains two blocks C and D which contains
		 * respectively element1 and element2
		 *
		 * Here the algorithm: From element1, I get the nearest parent block
		 * Then I will iterate on all parent blocks of element2 and test
		 * identity If not found, I have to iterate on parent block of element1
		 * And test again on all parent blocks of element2 ...
		 */
		private final Block getFirstCommonParentBlock(
				final EObject sourceElement, final EObject element2,
				final Block stopper) {
			Block result = getParentBlock(sourceElement);
			if (result != stopper) {
				if (!isParentBlock(element2, result, stopper)) {
					result = getFirstCommonParentBlock(result, element2,
							stopper);
				} // else, result is the first common parent block
			}
			return result;
		}

		private final boolean isParentBlock(final EObject element,
				final Block target, final Block stopper) {
			boolean result = false;
			Block parent = getParentBlock(element);
			if (parent != stopper) {
				if (parent == target) {
					result = true;
				} else {
					result = isParentBlock(parent, target, stopper);
				}
			}
			return result;
		}

		private final Block getParentBlock(final EObject element) {
			Block result = null;
			if (element != null) {
				if (element.eContainer() instanceof Block) {
					result = (Block) element.eContainer();
				} else {
					result = getParentBlock(element.eContainer());
				}
			}
			return result;
		}
	}

	/**
	 * To retrieve the type declaration which contains source element (which is
	 * at the beginning a method declaration element)
	 *
	 * @param element
	 * @return
	 */
	private final TypeDeclaration getTypeDeclaration(final EObject element) {
		TypeDeclaration result = null;
		if (element != null) {
			if (element instanceof TypeDeclaration) {
				result = (TypeDeclaration) element;
			} else {
				result = getTypeDeclaration(element.eContainer());
			}
		}
		return result;
	}

	/**
	 * To retrieve all sub types of parameter (type declaration element)
	 *
	 * @param contextClass
	 * @return
	 */
	private final Set<TypeDeclaration> getAllSubTypes(
			final TypeDeclaration contextClass) {
		Set<TypeDeclaration> result = new HashSet<TypeDeclaration>();
		if (contextClass != null) {
			for (TypeDeclaration currentClassDeclaration : this.allTypes) {
				if (isSuperTypeOf(contextClass, currentClassDeclaration)) {
					result.add(currentClassDeclaration);
					result.addAll(getAllSubTypes(currentClassDeclaration));
				}
			}
		}
		return result;
	}

	/**
	 * To compute a boolean which indicate if a type (self) is in parent
	 * hierarchy of an other type (typeDeclaration).
	 *
	 * @param self
	 * @param typeDeclaration
	 * @return true if self is a super type of typeDeclaration
	 */
	private final boolean isSuperTypeOf(final TypeDeclaration self,
			final TypeDeclaration typeDeclaration) {
		if (typeDeclaration.getSuperInterfaces().contains(self)) {
			return true;
		}
		for (TypeAccess superTypeAccess : typeDeclaration.getSuperInterfaces()) {
			if (superTypeAccess.getType() instanceof TypeDeclaration) {
				TypeDeclaration superType = (TypeDeclaration) superTypeAccess
						.getType();
				if (superType == self || isSuperTypeOf(self, superType)) {
					return true;
				}
			}
		}
		if (typeDeclaration instanceof ClassDeclaration) {
			ClassDeclaration classDeclaration = (ClassDeclaration) typeDeclaration;
			if (classDeclaration.getSuperClass() != null
					&& classDeclaration.getSuperClass().getType() == self) {
				return true;
			}
			if (classDeclaration.getSuperClass() != null
					&& classDeclaration.getSuperClass().getType() instanceof TypeDeclaration) {
				TypeDeclaration superType = (TypeDeclaration) classDeclaration
						.getSuperClass().getType();
				if (isSuperTypeOf(self, superType)) {
					return true;
				}
			}
		}
		return false;
	}

	private static final VariableDeclaration getVariableDeclaration(
			final AbstractMethodInvocation abstractMethodInvocation) {
		VariableDeclaration result = null;
		if (abstractMethodInvocation instanceof MethodInvocation) {
			MethodInvocation methodInvocation = (MethodInvocation) abstractMethodInvocation;
			if ((methodInvocation.getExpression() != null)
					&& (methodInvocation.getExpression() instanceof SingleVariableAccess)) {
				SingleVariableAccess singleVariableAccess = (SingleVariableAccess) methodInvocation
						.getExpression();
				result = singleVariableAccess.getVariable();
			}
		}
		return result;
	}

	private final Set<TypeDeclaration> getFilteredPotentialTypes(
			final VariableDeclaration variableDeclaration) {
		List<VariableDeclaration> parents = new ArrayList<VariableDeclaration>();
		Set<TypeDeclaration> result = getBasicFilteredPotentialTypes(
				variableDeclaration, parents);
		return result;
	}

	private final Set<TypeDeclaration> getBasicFilteredPotentialTypes(
			final VariableDeclaration source,
			final List<VariableDeclaration> parents) {
		Set<TypeDeclaration> result = new HashSet<TypeDeclaration>();
		if (!parents.contains(source)) {
			parents.add(source);

			Expression initializer = source.getInitializer();
			if ((initializer != null)
					&& (initializer instanceof ClassInstanceCreation)) {
				ClassInstanceCreation classInstanceCreation = (ClassInstanceCreation) initializer;
				if (classInstanceCreation.getType().getType() instanceof TypeDeclaration) {
					result.add((TypeDeclaration) classInstanceCreation
							.getType().getType());
				}
			}
			result.addAll(filterAssignement(source, parents));
		}
		return result;
	}

	private final Set<TypeDeclaration> filterAssignement(
			final VariableDeclaration source,
			final List<VariableDeclaration> parents) {
		Set<TypeDeclaration> result = new HashSet<TypeDeclaration>();
		for (SingleVariableAccess access : source.getUsageInVariableAccess()) {
			EObject container = access.eContainer();
			if (container instanceof Assignment) {
				Assignment assignment = (Assignment) container;
				Expression expression = assignment.getRightHandSide();
				if (expression instanceof ClassInstanceCreation) {
					ClassInstanceCreation classInstanceCreation = (ClassInstanceCreation) expression;
					if (classInstanceCreation.getType().getType() instanceof TypeDeclaration) {
						result.add((TypeDeclaration) classInstanceCreation
								.getType().getType());
					}
				} else if (expression instanceof SingleVariableAccess) {
					/*
					 * potential infinite recursion
					 *
					 * Object tmp; Object src = tmp; ... tmp = src;
					 */
					SingleVariableAccess singleVariableAccess = (SingleVariableAccess) expression;
					result.addAll(getBasicFilteredPotentialTypes(
							singleVariableAccess.getVariable(), parents));
				}
			}
		}
		return result;
	}

}
