/*******************************************************************************
 * Copyright (c) 2000, 2021 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.ui.tests.core;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

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

import org.junit.Test;

import org.eclipse.core.runtime.Assert;

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.AnnotatableType;
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.MethodReference;
import org.eclipse.jdt.core.dom.ModuleDirective;
import org.eclipse.jdt.core.dom.ModulePackageAccess;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.Pattern;
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.dom.HierarchicalASTVisitor;

@SuppressWarnings("javadoc")
public class HierarchicalASTVisitorTest {
	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).
		 */

		@Override
		public boolean visit(ASTNode node) {
			registerCall(ASTNode.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(ASTNode node) {
			super.visit(node);
		}
		@Override
		public void endVisit(ASTNode node) {
			registerCall(ASTNode.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(ASTNode node) {
			super.visit(node);
		}

		@Override
		public boolean visit(BodyDeclaration node) {
			registerCall(BodyDeclaration.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(BodyDeclaration node) {
			super.visit(node);
		}
		@Override
		public void endVisit(BodyDeclaration node) {
			registerCall(BodyDeclaration.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(BodyDeclaration node) {
			super.visit(node);
		}

		@Override
		public boolean visit(AbstractTypeDeclaration node) {
			registerCall(AbstractTypeDeclaration.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(AbstractTypeDeclaration node) {
			super.visit(node);
		}
		@Override
		public void endVisit(AbstractTypeDeclaration node) {
			registerCall(AbstractTypeDeclaration.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(AbstractTypeDeclaration node) {
			super.visit(node);
		}

		@Override
		public boolean visit(Comment node) {
			registerCall(Comment.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(Comment node) {
			super.visit(node);
		}
		@Override
		public void endVisit(Comment node) {
			registerCall(Comment.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(Comment node) {
			super.visit(node);
		}

		@Override
		public boolean visit(Expression node) {
			registerCall(Expression.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(Expression node) {
			super.visit(node);
		}
		@Override
		public void endVisit(Expression node) {
			registerCall(Expression.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(Expression node) {
			super.visit(node);
		}

		@Override
		public boolean visit(Annotation node) {
			registerCall(Annotation.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(Annotation node) {
			super.visit(node);
		}
		@Override
		public void endVisit(Annotation node) {
			registerCall(Annotation.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(Annotation node) {
			super.visit(node);
		}

		@Override
		public boolean visit(MethodReference node) {
			registerCall(MethodReference.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(MethodReference node) {
			super.visit(node);
		}
		@Override
		public void endVisit(MethodReference node) {
			registerCall(MethodReference.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(MethodReference node) {
			super.visit(node);
		}

		@Override
		public boolean visit(Name node) {
			registerCall(Name.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(Name node) {
			super.visit(node);
		}
		@Override
		public void endVisit(Name node) {
			registerCall(Name.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(Name node) {
			super.visit(node);
		}

		@Override
		public boolean visit(ModuleDirective node) {
			registerCall(ModuleDirective.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(ModuleDirective node) {
			super.visit(node);
		}
		@Override
		public void endVisit(ModuleDirective node) {
			registerCall(ModuleDirective.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(ModuleDirective node) {
			super.visit(node);
		}

		@Override
		public boolean visit(ModulePackageAccess node) {
			registerCall(ModulePackageAccess.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(ModulePackageAccess node) {
			super.visit(node);
		}
		@Override
		public void endVisit(ModulePackageAccess node) {
			registerCall(ModulePackageAccess.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(ModulePackageAccess node) {
			super.visit(node);
		}

		@Override
		public boolean visit(Pattern node) {
			registerCall(Pattern.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(Pattern node) {
			super.visit(node);
		}
		@Override
		public void endVisit(Pattern node) {
			registerCall(Pattern.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(Pattern node) {
			super.visit(node);
		}

		@Override
		public boolean visit(Statement node) {
			registerCall(Statement.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(Statement node) {
			super.visit(node);
		}
		@Override
		public void endVisit(Statement node) {
			registerCall(Statement.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(Statement node) {
			super.visit(node);
		}

		@Override
		public boolean visit(Type node) {
			registerCall(Type.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(Type node) {
			super.visit(node);
		}
		@Override
		public void endVisit(Type node) {
			registerCall(Type.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(Type node) {
			super.visit(node);
		}

		@Override
		public boolean visit(AnnotatableType node) {
			registerCall(AnnotatableType.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(AnnotatableType node) {
			super.visit(node);
		}
		@Override
		public void endVisit(AnnotatableType node) {
			registerCall(AnnotatableType.class);
		}
		@SuppressWarnings("unused") // called reflectively
		public void superEndVisit(AnnotatableType node) {
			super.visit(node);
		}

		@Override
		public boolean visit(VariableDeclaration node) {
			registerCall(VariableDeclaration.class);
			return false;
		}
		@SuppressWarnings("unused") // called reflectively
		public void superVisit(VariableDeclaration node) {
			super.visit(node);
		}
		@Override
		public void endVisit(VariableDeclaration node) {
			registerCall(VariableDeclaration.class);
		}
		@SuppressWarnings("unused") // called reflectively
		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<? extends ASTNode> 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<? extends ASTNode> clazz, boolean isEndVisit) {
			Assert.isTrue(ASTNode.class.isAssignableFrom(clazz));
			try {
				TestHierarchicalASTVisitor.class.getDeclaredMethod(getVisitMethodName(isEndVisit), 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), 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<? extends ASTNode> fNodeClassForCalledMethod= null;

		private void _checkMethodCallsSuperclassMethod(Class<? extends ASTNode> 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 ? getVisitMethodName(isEndVisit) : "superVisit", clazz);
				method.invoke(this, new Object[] { null });
			} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
				/* NoSuchMethodException should have already been discovered by
				 * hasRequiredMethodsForNonLeaf(..)
				 */
				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, isEndVisit);
		}
		private void checkSuperclassMethodCalled(Class<? extends ASTNode> clazz, 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.
			 */
			assertEquals(getSuperMethodNotCalledMessageFor(clazz, isEndVisit), clazz.getSuperclass(), fNodeClassForCalledMethod);
		}
		private String getSuperMethodNotCalledMessageFor(Class<? extends ASTNode> clazz, boolean isEndVisit) {
			return getMethodSignatureFor(clazz, isEndVisit) + " in HierarchicalASTVisitor should call " + getMethodSignatureFor(clazz.getSuperclass(), isEndVisit) + ", the visitor method for its superclass.";
		}

		private void registerCall(Class<? extends ASTNode> 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 Set<Class<? extends ASTNode>> fLeaves;

	@Test
	public void test() {
		fLeaves= getLeafASTNodeDescendants();
		Set<Class<? extends ASTNode>> 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<? extends ASTNode> 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<Class<? extends ASTNode>> hierarchyClasses, boolean isEndVisit) {
		while (hierarchyClasses.hasNext()) {
			Class<? extends ASTNode> descendant= 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<Class<? extends ASTNode>> hierarchyClasses, boolean isEndVisit) {
		while (hierarchyClasses.hasNext()) {
			Class<? extends ASTNode> descendant= hierarchyClasses.next();
			if (!ASTNode.class.equals(descendant))
				TestHierarchicalASTVisitor.checkMethodCallsSuperclassMethod(descendant, isLeaf(descendant), isEndVisit);
		}
	}

	private void checkHierarchicalASTVisitorMethodExistsFor(Class<? extends ASTNode> nodeClass, boolean isEndVisit) {
		Assert.isTrue(ASTNode.class.isAssignableFrom(nodeClass));
		try {
			HierarchicalASTVisitor.class.getDeclaredMethod(getVisitMethodName(isEndVisit), nodeClass);
		} catch (NoSuchMethodException e) {
			String signature= getVisitMethodName(isEndVisit) + "(" + getSimpleName(nodeClass) + ")";
			fail("HierarchicalASTVisitor must be updated to reflect a change in the ASTNode hierarchy.  No method " + signature + " was found in HierarchicalASTVisitor.");
		}
	}

	private static String getVisitMethodName(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 isEndVisit) {
		return getVisitMethodName(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<Class<? extends ASTNode>> computeAllDescendantsFromLeaves(Iterator<Class<? extends ASTNode>> leaves, Class<? extends ASTNode> root) {
		Set<Class<? extends ASTNode>> all= new HashSet<>();
		while (leaves.hasNext()) {
			Class<? extends ASTNode> leaf= leaves.next();
			addAllAncestorsInclusive(leaf, root, all);
		}
		return all;
	}

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

		Class<?> ancestor= from;
		while (!ancestor.equals(to)) {
			@SuppressWarnings("unchecked")
			Class<? extends ASTNode> nodeType= (Class<? extends ASTNode>) ancestor;
			set.add(nodeType);
			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<Class<? extends ASTNode>> getLeafASTNodeDescendants() {
		Set<Class<? extends ASTNode>> result= new HashSet<>();
		for (Method method : ASTVisitor.class.getMethods()) {
			if (isVisitMethod(method)) {
				@SuppressWarnings("unchecked")
					Class<? extends ASTNode> nodeType= (Class<? extends ASTNode>) method.getParameterTypes()[0];
				result.add(nodeType);
			}
		}
		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]);
	}
}
