/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.ui.tests.core;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.Comment;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.VariableDeclaration;

import org.eclipse.jdt.internal.corext.Assert;
import org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor;

public class HierarchicalASTVisitorTest extends TestCase {
	private static class TestHierarchicalASTVisitor extends HierarchicalASTVisitor {

		//---- BEGIN <REGION TO BE UPDATED IN RESPONSE TO ASTNode HIERARCHY CHANGES> ---------------------
		/* ******************************************************************************
		 * Whereas the other parts of this test should be relatively static,
		 * this portion of the file must be maintained in response to
		 * changes that occur in the ASTNode hierarchy (and, thus, the ASTVisitor).
		 * Such changes would include addition or removal of node types to or from
		 * the hierarchy, or changes in the superclass/subclass relationships
		 * among node classes.  Such changes necessitate, also, changes in the
		 * HierarchicalASTVisitor itself, whose structure and behaviour this test
		 * verifies.
		 * 
		 * The changes that must be made to this file in response to such changes in
		 * the ASTNode hierarchy are localized here and limited to maintenance of the
		 * following set of visit(XX node), superVisit(XX node), endVisit(XX node),
		 * and superEndVisit(XX node) implementations.
		 * There should be one such quadruple for each non-leaf ASTNode descendant class,
		 * including ASTNode itself.
		 * 
		 * *****************************************************************************/

		/* Here, for each non-leaf ASTNode descendant class, the visit(XX) method
		 * is overridden to call registerCall(XX.class), and a void superVisit
		 * (XX node) method is provided, which simply calls super.visit(XX).
		 * Accordingly for endVisit(XX) and superEndVisit(XX).
		 */

		public boolean visit(ASTNode node) {
			registerCall(ASTNode.class);
			return false;
		}
		public void superVisit(ASTNode node) {
			super.visit(node);
		}
		public void endVisit(ASTNode node) {
			registerCall(ASTNode.class);
		}
		public void superEndVisit(ASTNode node) {
			super.visit(node);
		}

		public boolean visit(Expression node) {
			registerCall(Expression.class);
			return false;
		}
		public void superVisit(Expression node) {
			super.visit(node);
		}
		public void endVisit(Expression node) {
			registerCall(Expression.class);
		}
		public void superEndVisit(Expression node) {
			super.visit(node);
		}

		public boolean visit(Annotation node) {
			registerCall(Annotation.class);
			return false;
		}
		public void superVisit(Annotation node) {
			super.visit(node);
		}
		public void endVisit(Annotation node) {
			registerCall(Annotation.class);
		}
		public void superEndVisit(Annotation node) {
			super.visit(node);
		}

		public boolean visit(Name node) {
			registerCall(Name.class);
			return false;
		}
		public void superVisit(Name node) {
			super.visit(node);
		}
		public void endVisit(Name node) {
			registerCall(Name.class);
		}
		public void superEndVisit(Name node) {
			super.visit(node);
		}

		public boolean visit(BodyDeclaration node) {
			registerCall(BodyDeclaration.class);
			return false;
		}
		public void superVisit(BodyDeclaration node) {
			super.visit(node);
		}
		public void endVisit(BodyDeclaration node) {
			registerCall(BodyDeclaration.class);
		}
		public void superEndVisit(BodyDeclaration node) {
			super.visit(node);
		}

		public boolean visit(AbstractTypeDeclaration node) {
			registerCall(AbstractTypeDeclaration.class);
			return false;
		}
		public void superVisit(AbstractTypeDeclaration node) {
			super.visit(node);
		}
		public void endVisit(AbstractTypeDeclaration node) {
			registerCall(AbstractTypeDeclaration.class);
		}
		public void superEndVisit(AbstractTypeDeclaration node) {
			super.visit(node);
		}

		public boolean visit(Comment node) {
			registerCall(Comment.class);
			return false;
		}
		public void superVisit(Comment node) {
			super.visit(node);
		}
		public void endVisit(Comment node) {
			registerCall(Comment.class);
		}
		public void superEndVisit(Comment node) {
			super.visit(node);
		}

		public boolean visit(Type node) {
			registerCall(Type.class);
			return false;
		}
		public void superVisit(Type node) {
			super.visit(node);
		}
		public void endVisit(Type node) {
			registerCall(Type.class);
		}
		public void superEndVisit(Type node) {
			super.visit(node);
		}

		public boolean visit(Statement node) {
			registerCall(Statement.class);
			return false;
		}
		public void superVisit(Statement node) {
			super.visit(node);
		}
		public void endVisit(Statement node) {
			registerCall(Statement.class);
		}
		public void superEndVisit(Statement node) {
			super.visit(node);
		}

		public boolean visit(VariableDeclaration node) {
			registerCall(VariableDeclaration.class);
			return false;
		}
		public void superVisit(VariableDeclaration node) {
			super.visit(node);
		}
		public void endVisit(VariableDeclaration node) {
			registerCall(VariableDeclaration.class);
		}
		public void superEndVisit(VariableDeclaration node) {
			super.visit(node);
		}

		//---- END <REGION TO BE UPDATED IN RESPONSE TO ASTNode HIERARCHY CHANGES> ----------------------

		/**
		 * Verifies that the visit(XX) method in HierarchicalASTVisitor calls
		 * visit(YY), where XX is the name of <code>clazz</code> and YY is the
		 * name of the superclass of clazz.
		 * 
		 * <code>clazz</code> must be a <b>proper</b> descendant of ASTNode (<code>clazz</code> is not ASTNode).
		 */
		private static void checkMethodCallsSuperclassMethod(Class clazz, boolean isLeaf, boolean isEndVisit) {
			Assert.isTrue(ASTNode.class.isAssignableFrom(clazz));
			Assert.isTrue(!ASTNode.class.equals(clazz));

			TestHierarchicalASTVisitor visitor= new TestHierarchicalASTVisitor();
			visitor._checkMethodCallsSuperclassMethod(clazz, isLeaf, isEndVisit);
		}

		/**
		 * This class must have certain methods corresponding to the
		 * ASTNode descendant class <code>clazz</code>.
		 * This method reflectively verifies that they are present.
		 */
		private static void checkRequiredMethodsForNonLeaf(Class clazz, boolean isEndVisit) {
			Assert.isTrue(ASTNode.class.isAssignableFrom(clazz));
			try {
				TestHierarchicalASTVisitor.class.getDeclaredMethod(getMethodNameFor(clazz, isEndVisit), new Class[] { clazz });
			} catch (NoSuchMethodException e) {
				fail("Test must be updated since TestHierarchicalASTVisitor (declared within test class), is missing a method corresponding to non-leaf node class '" + getSimpleName(clazz) + "'");
			}
			try {
				TestHierarchicalASTVisitor.class.getDeclaredMethod(getSuperVisitName(isEndVisit), new Class[] { clazz });
			} catch (NoSuchMethodException e) {
				fail("Test must be updated since TestHierarchicalASTVisitor (declared within test class), is missing a method corresponding to non-leaf node class '" + getSimpleName(clazz) + "'");
			}
		}

		private Class fNodeClassForCalledMethod= null;

		private void _checkMethodCallsSuperclassMethod(Class clazz, boolean isLeaf, boolean isEndVisit) {
			/* Invoke a method which will result in the execution of
			 * HierarchicalASTVisitor's implementation of visit(XX), where 
			 * XX is the name of clazz.
			 * 
			 * If clazz is a leaf, we can invoke visit(XX) directly.
			 * Otherwise, we must invoke superVisit(XX), (in this class)
			 * which calls super.visit(XX), since visit(XX) is overridden in
			 * this class.
			 * 
			 * The parameter passed to visit(XX) or superVisit(XX)
			 * is null.  If there ever was any requirement that the
			 * parameter to visit(XX) methods, be non-null, we would simply have
			 * to reflectively instantiate an appropriately typed node.
			 */
			try {
				Method method= TestHierarchicalASTVisitor.class.getMethod(isLeaf ? getMethodNameFor(clazz, isEndVisit) : "superVisit", new Class[] { clazz });
				method.invoke(this, new Object[] { null });
			} catch (NoSuchMethodException e) {
				/* This should have already been discovered by
				 * hasRequiredMethodsForNonLeaf(..)
				 */
				e.printStackTrace();
				Assert.isTrue(false);
			} catch (IllegalAccessException e) {
				e.printStackTrace();
				Assert.isTrue(false);
			} catch (InvocationTargetException e) {
				e.printStackTrace();
				Assert.isTrue(false);
			}

			/*
			 * Verify that the method invokation caused
			 * a call to visit(YY), where YY is the name of the superclass of
			 * clazz. (Also, verify that no other visit(ZZ) method was called).
			 */
			checkSuperclassMethodCalled(clazz, isLeaf, isEndVisit);
		}
		private void checkSuperclassMethodCalled(Class clazz, boolean isLeaf, boolean isEndVisit) {
			Assert.isNotNull(clazz.getSuperclass());
			/*
			 * This class' implementations of the visit(YY) methods (for non-
			 * leaf YY) cause fNodeClassForCalledMethod to be set to YY.class.
			 * Such an implementation will be the one executed when a visit(XX)
			 * implementation in HierarchicalASTVisitor calls the visit(YY)
			 * method corresponding to XX's superclass, YY. We check here that
			 * fNodeClassForCalledMethod was set to the superclass of clazz.
			 */
			assertTrue(getSuperMethodNotCalledMessageFor(clazz, isLeaf, isEndVisit), clazz.getSuperclass().equals(fNodeClassForCalledMethod));
		}
		private String getSuperMethodNotCalledMessageFor(Class clazz, boolean isLeaf, boolean isEndVisit) {
			return getMethodSignatureFor(clazz, isLeaf, isEndVisit) + " in HierarchicalASTVisitor should call " + getMethodSignatureFor(clazz.getSuperclass(), false, isEndVisit) + ", the visitor method for its superclass.";
		}

		private void registerCall(Class nodeClassForMethod) {
			assertNull("The invocation of a visit(XX) method in HierarchicalASTVisitor has caused " +
					"more than one other visit(XX) method to be called.  Every visit(XX) method in " +
					"HierarchicalASTVisitor, except visit(ASTNode), should simply call visit(YY), " +
					"where YY is the superclass of XX.", fNodeClassForCalledMethod);
			fNodeClassForCalledMethod= nodeClassForMethod;
		}
	}

	private static final Class THIS_CLASS= HierarchicalASTVisitorTest.class;

	private Set/*<Class>*/ fLeaves;

	public HierarchicalASTVisitorTest(String name) {
		super(name);
	}

	public static Test allTests() {
		return new TestSuite(THIS_CLASS);
	}

	public static Test suite() {
		return new TestSuite(THIS_CLASS);
	}

	public void test() {
		fLeaves= getLeafASTNodeDescendants();
		Set allASTNodeDescendants= computeAllDescendantsFromLeaves(fLeaves.iterator(), ASTNode.class);

		checkAllMethodsForHierarchyExist(allASTNodeDescendants.iterator(), false);
		checkAllMethodsForHierarchyExist(allASTNodeDescendants.iterator(), true);
		checkMethodsCallSuperclassMethod(allASTNodeDescendants.iterator(), false);
		checkMethodsCallSuperclassMethod(allASTNodeDescendants.iterator(), true);
	}

	private boolean isLeaf(Class clazz) {
		return fLeaves.contains(clazz);
	}

	/**
	 * For both HierarchicalASTVisitor and a subsequent part of this test to be correct,
	 * HierarchicalASTVisitor and TestHierarchicalASTVisitor must declare certain methods,
	 * each one corresponding to a class in the ASTNode hierarchy.  Specifically, 
	 * HierarchicalASTVisitor must declare a method corresponding to each class in the hierarchy,
	 * whereas TestHierarchicalASTVisitor must declare a pair of methods for each non-leaf
	 * class in the ASTNode hierarchy.
	 * 
	 * This method verifies that these required methods exist, and suggests the updates
	 * that are needed to properly maintain the set of methods.
	 */
	private void checkAllMethodsForHierarchyExist(Iterator hierarchyClasses, boolean isEndVisit) {
		while (hierarchyClasses.hasNext()) {
			Class descendant= (Class) hierarchyClasses.next();
			checkHierarchicalASTVisitorMethodExistsFor(descendant, isEndVisit);
			if (!isLeaf(descendant))
				TestHierarchicalASTVisitor.checkRequiredMethodsForNonLeaf(descendant, isEndVisit);
		}
	}

	/**
	 * All visit(XX) implementations in HierarchicalASTVisitor, each
	 * corresponding to a class XX, must call visit(YY), where YY is the
	 * superclass of YY, unless XX is ASTNode. This method verifies this using
	 * reflection and a contrived subclass of HierarchicalASTVisitor,
	 * TestHierarchicalASTVisitor.
	 */
	private void checkMethodsCallSuperclassMethod(Iterator hierarchyClasses, boolean isEndVisit) {
		while (hierarchyClasses.hasNext()) {
			Class descendant= (Class) hierarchyClasses.next();
			if (!ASTNode.class.equals(descendant))
				TestHierarchicalASTVisitor.checkMethodCallsSuperclassMethod(descendant, isLeaf(descendant), isEndVisit);
		}
	}

	private void checkHierarchicalASTVisitorMethodExistsFor(Class nodeClass, boolean isEndVisit) {
		Assert.isTrue(ASTNode.class.isAssignableFrom(nodeClass));
		try {
			HierarchicalASTVisitor.class.getDeclaredMethod(getMethodNameFor(nodeClass, isEndVisit), new Class[] { nodeClass });
		} catch (NoSuchMethodException e) {
			String signature= getMethodNameFor(nodeClass, isEndVisit) + "(" + getSimpleName(nodeClass) + ")";
			assertTrue("HierarchicalASTVisitor must be updated to reflect a change in the ASTNode hierarchy.  No method " + signature + " was found in HierarchicalASTVisitor.", false);
		}
	}

	private static String getMethodNameFor(Class clazz, boolean isEndVisit) {
		return isEndVisit ? "endVisit" : "visit";
	}

	private static String getSuperVisitName(boolean isEndVisit) {
		return isEndVisit ? "superEndVisit" : "superVisit";
	}
	
	private static String getSimpleName(Class clazz) {
		String qualified= clazz.getName();
		return qualified.substring(qualified.lastIndexOf('.') + 1);
	}

	private static String getMethodSignatureFor(Class clazz, boolean isLeaf, boolean isEndVisit) {
		return getMethodNameFor(clazz, isEndVisit) + "(" + getSimpleName(clazz) + ")";
	}

	/**
	 * Finds the set of all descendants of <code>root</code> which are not proper descendants
	 * of a class in the sequence <code>leaves</code>.  This will include <code>root</code>
	 * and all the elements of <code>leaves</code>.
	 */
	private static Set computeAllDescendantsFromLeaves(Iterator leaves, Class root) {
		Set all= new HashSet();
		while (leaves.hasNext()) {
			Class leaf= (Class) leaves.next();
			addAllAncestorsInclusive(leaf, root, all);
		}
		return all;
	}

	private static void addAllAncestorsInclusive(Class from, Class to, Set set) {
		Assert.isTrue(to.isAssignableFrom(from));
		Assert.isTrue(!from.isInterface());
		Assert.isTrue(!to.isInterface());

		Class ancestor= from;
		while (!ancestor.equals(to)) {
			set.add(ancestor);
			ancestor= ancestor.getSuperclass();
			if (ancestor == null) {
				Assert.isTrue(false);
				/* not expected, given assertions passed above */
			}
		}
		set.add(to);
	}

	/**
	 * Returns all the leaf node classes (classes with no subclasses) in the
	 * ASTNode . Since every non-leaf ASTNode descendant (incl. ASTNode)
	 * is abstract, the set of leaf ASTNode descendants is the set of concrete
	 * ASTNode descendants.
	 * 
	 * If ASTVisitor is maintained, this set will be the set of classes for which
	 * ASTVisitor has visit(..) methods.  We use this property to compute the set,
	 * which means that we are as up-to-date as ASTVisitor (to be more
	 * "up-to-date" would be to require something that HierarchicalASTVisitor would,
	 * semantically, not be able to provide anyway!).
	 */
	private static Set getLeafASTNodeDescendants() {
		Set result= new HashSet();
		Method[] methods= ASTVisitor.class.getMethods();
		for (int i= 0; i < methods.length; i++) {
			Method method= methods[i];
			if (isVisitMethod(method)) {
				result.add(method.getParameterTypes()[0]);
			}
		}
		return result;
	}
	private static boolean isVisitMethod(Method method) {
		if (!"visit".equals(method.getName()))
			return false;

		Class[] parameters= method.getParameterTypes();
		return parameters.length == 1 && ASTNode.class.isAssignableFrom(parameters[0]);
	}
}
