/*******************************************************************************
 * Copyright (c) 2005, 2011 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.common.core.internal.utility.jdt;

import java.util.HashSet;
import java.util.List;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.IAnnotationBinding;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TypeLiteral;
import org.eclipse.jpt.common.core.internal.utility.SimpleTextRange;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.JavaType;
import org.eclipse.jpt.common.utility.MethodSignature;
import org.eclipse.jpt.common.utility.internal.SimpleJavaType;
import org.eclipse.jpt.common.utility.internal.SimpleMethodSignature;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable;

/**
 * Convenience methods for dealing with JDT ASTs.
 */
public class ASTTools {

	/**
	 * Build an AST without method bodies for the specified compilation unit
	 * with its bindings resolved (and the resultant performance hit).
	 */
	public static CompilationUnit buildASTRoot(ICompilationUnit compilationUnit) {
		ASTParser parser = ASTParser.newParser(AST.JLS3);
		parser.setSource(compilationUnit);
		parser.setIgnoreMethodBodies(true);  // we don't need method bodies
		parser.setResolveBindings(true);
		parser.setBindingsRecovery(true);  // see bugs 196200, 222735
		return (CompilationUnit) parser.createAST(null);
	}


	// ********** JDT DOM **********

	public static String resolveEnum(Expression expression) {
		if (expression == null) {
			return null;
		}
		switch (expression.getNodeType()) {
			case ASTNode.QUALIFIED_NAME:
			case ASTNode.SIMPLE_NAME:
				return resolveEnum((Name) expression);
			default:
				return null;
		}
	}

	public static String resolveEnum(Name enumExpression) {
		IBinding binding = enumExpression.resolveBinding();
		if (binding == null) {
			return null;  // TODO figure out why this is null sometimes
		}
		if (binding.getKind() != IBinding.VARIABLE) {
			return null;
		}
		IVariableBinding variableBinding = (IVariableBinding) binding;
		return variableBinding.getType().getQualifiedName() + '.' + variableBinding.getName();
	}

	/**
	 * Return the fully-qualified name of the specified node's annotation
	 * class.
	 */
	public static String resolveAnnotation(Annotation node) {
		IAnnotationBinding annotationBinding = node.resolveAnnotationBinding();
		if (annotationBinding == null) {
			return null;
		}
		ITypeBinding annotationTypeBinding = annotationBinding.getAnnotationType();
		return (annotationTypeBinding == null) ? null : annotationTypeBinding.getQualifiedName();
	}
	
	/**
	 * If the specified expression is a type literal, return the type's fully-
	 * qualified name. Return null otherwise.
	 */
	public static String resolveFullyQualifiedName(Expression expression) {
		ITypeBinding resolvedTypeBinding = resolveTypeBinding(expression);
		return (resolvedTypeBinding == null) ? null : resolvedTypeBinding.getQualifiedName();
	}
	
	/**
	 * If the specified expression is an array initializer, return an an iterable
	 * on the types' fully qualfified names.  
	 * The results may include nulls.
	 */
	public static Iterable<String> resolveFullyQualifiedNames(Expression expression) {
		return new TransformationIterable<ITypeBinding, String>(resolveTypeBindings(expression)) {
			@Override
			protected String transform(ITypeBinding o) {
				return (o == null) ? null : o.getQualifiedName();
			}
		};
	}
	
	/**
	 * If the specified expression is a type literal, return the corresponding
	 * type binding.
	 */
	public static ITypeBinding resolveTypeBinding(Expression expression) {
		if (expression != null && expression.getNodeType() == ASTNode.TYPE_LITERAL) {
			return ((TypeLiteral) expression).getType().resolveBinding();
		}
		return null;
	}
	
	/**
	 * If the specified expression is an array initializer, return an iterable of
	 * the corresponding type bindings for each sub-expression.
	 * The result may include <code>null</code> elements.
	 */
	public static Iterable<ITypeBinding> resolveTypeBindings(Expression expression) {
		return (expression != null && expression.getNodeType() == ASTNode.ARRAY_INITIALIZER) ?
				resolveTypeBindings((ArrayInitializer) expression) :
				EmptyIterable.<ITypeBinding>instance();
	}
	
	private static Iterable<ITypeBinding> resolveTypeBindings(ArrayInitializer arrayExpression) {
		@SuppressWarnings("unchecked")
		Iterable<Expression> expressions = arrayExpression.expressions();
		return new TransformationIterable<Expression, ITypeBinding>(expressions) {
			@Override
			protected ITypeBinding transform(Expression expression) {
				return resolveTypeBinding(expression);
			}
		};
	}
	
	public static MethodSignature buildMethodSignature(MethodDeclaration methodDeclaration) {
		return new SimpleMethodSignature(
				methodDeclaration.getName().getFullyQualifiedName(),
				buildParameterTypes(methodDeclaration)
			);
	}

	public static JavaType[] buildParameterTypes(MethodDeclaration methodDeclaration) {
		List<SingleVariableDeclaration> parameters = parameters(methodDeclaration);
		int len = parameters.size();
		JavaType[] parameterTypes = new JavaType[len];
		for (int i = 0; i < len; i++) {
			ITypeBinding type = parameters.get(i).getType().resolveBinding();
			parameterTypes[i] = new SimpleJavaType(type.getQualifiedName(), type.getDimensions());
		}
		return parameterTypes;
	}

	// minimize scope of suppressed warnings
	@SuppressWarnings("unchecked")
	private static List<SingleVariableDeclaration> parameters(MethodDeclaration methodDeclaration) {
		return methodDeclaration.parameters();
	}

	/**
	 * Return whether the specified expression is a type literal and the type binding
	 * corresponding to the specified type name exists in the type
	 * literal's inheritance hierarchy (superclasses and interfaces).
	 * Return null otherwise.
	 */
	public static boolean typeIsSubTypeOf(Expression expression, String searchTypeName) {
		return findTypeInHierarchy(expression, searchTypeName) != null;
	}

	/**
	 * If the specified expression is a type literal, return the type binding
	 * corresponding to the specified type name if it exists in the type
	 * literal's inheritance hierarchy (superclasses and interfaces).
	 * Return null otherwise.
	 */
	public static ITypeBinding findTypeInHierarchy(Expression expression, String searchTypeName) {
		ITypeBinding typeBinding = resolveTypeBinding(expression);
		return (typeBinding == null) ? null : findTypeInHierarchy(typeBinding, searchTypeName);
	}

	/**
	 * Return whether a type binding with the specified type name exists in
	 * the specified type binding's inheritance hierarchy (superclasses
	 * and interfaces).
	 */
	public static boolean typeIsSubTypeOf(ITypeBinding typeBinding, String searchTypeName) {
		return findTypeInHierarchy(typeBinding, searchTypeName) != null;
	}

	/**
	 * Return the type binding corresponding to the specified type name if it
	 * exists in the specified type binding's inheritance hierarchy (superclasses
	 * and interfaces). Return null otherwise.
	 */
	public static ITypeBinding findTypeInHierarchy(ITypeBinding typeBinding, String searchTypeName) {
		return findTypeInHierarchy(typeBinding, searchTypeName, new HashSet<String>());
	}

	private static ITypeBinding findTypeInHierarchy(ITypeBinding typeBinding, String searchTypeName, HashSet<String> visited) {
		String typeName = typeBinding.getTypeDeclaration().getQualifiedName();
		if (visited.contains(typeName)) {
			return null;
		}
		if (typeName.equals(searchTypeName)) {
			return typeBinding;
		}
		visited.add(typeName);
		
		ITypeBinding interfaceBinding = findTypeInInterfaces(typeBinding, searchTypeName, visited);
		if (interfaceBinding != null) {
			return interfaceBinding;
		}
		
		return findTypeInSuperclasses(typeBinding, searchTypeName, visited);
	}

	private static ITypeBinding findTypeInInterfaces(ITypeBinding typeBinding, String searchTypeName, HashSet<String> visited) {
		ITypeBinding[] interfaceBindings = typeBinding.getInterfaces();
		for (ITypeBinding interfaceBinding : interfaceBindings) {  // recurse up interfaces
			ITypeBinding result = findTypeInHierarchy(interfaceBinding, searchTypeName, visited);
			if (result != null) {
 				return result;
			}
		}
		return null;
	}
	
	private static ITypeBinding findTypeInSuperclasses(ITypeBinding typeBinding, String searchTypeName, HashSet<String> visited) {
		ITypeBinding superBinding = typeBinding.getSuperclass();
		if (superBinding != null) {  // recurse up superclasses
			ITypeBinding result = findTypeInHierarchy(superBinding, searchTypeName, visited);
			if (result != null) {
				return result;
			}
		}
		return null;		
	}
	/**
	 * Return whether the specified expression is a type literal and the type binding
	 * corresponding to the specified interface name exists in the type
	 * literal's inheritance hierarchy (superclasses and interfaces).
	 * Return null otherwise.
	 */
	public static boolean typeImplementsInterface(Expression expression, String searchInterfaceName) {
		ITypeBinding typeBinding = resolveTypeBinding(expression);
		if (typeBinding == null) {
			return false;
		}
		return findInterfaceInHierarchy(typeBinding, searchInterfaceName) != null;
	}

	/**
	 * Return whether a type binding with the specified interface name exists in
	 * the specified type binding's inheritance hierarchy (superclasses
	 * and interfaces).
	 */
	public static boolean typeImplementsInterface(ITypeBinding typeBinding, String searchInterfaceName) {
		return findInterfaceInHierarchy(typeBinding, searchInterfaceName) != null;
	}
	
	private static ITypeBinding findInterfaceInHierarchy(ITypeBinding typeBinding, String searchInterfaceName) {
		HashSet<String> visited = new HashSet<String>();
		ITypeBinding interfaceBinding = findTypeInInterfaces(typeBinding, searchInterfaceName, visited);
		if (interfaceBinding != null) {
			return interfaceBinding;
		}
		
		return findTypeInSuperclasses(typeBinding, searchInterfaceName, visited);

	}

	/**
	 * Build and return a text range for the specified AST node.
	 */
	public static TextRange buildTextRange(ASTNode astNode) {
		return buildTextRange(astNode, null);
	}

	/**
	 * Build and return a text range for the specified AST node if it differs
	 * from the specified text range or the specified text range is
	 * <code>null</code>. If the AST node already matches the
	 * specified text range, simply return the text range unchanged.
	 */
	public static TextRange buildTextRange(ASTNode astNode, TextRange textRange) {
		int offset = astNode.getStartPosition();
		int length = astNode.getLength();
		int lineNumber = ((CompilationUnit) astNode.getRoot()).getLineNumber(offset);
		return (textRange == null) ?
				new SimpleTextRange(offset, length, lineNumber) :
				textRange.buildTextRange(offset, length, lineNumber);
	}
}
