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

import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jpt.common.core.utility.jdt.ModifiedDeclaration;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
import org.eclipse.jpt.common.utility.internal.predicate.PredicateAdapter;
import org.eclipse.jpt.common.utility.predicate.Predicate;

/**
 * Wrap any of the AST nodes that have modifiers (specifically, annotations);
 * i.e. BodyDeclaration, SingleVariableDeclaration, VariableDeclarationExpression,
 * and VariableDeclarationStatement.
 */
public class JDTModifiedDeclaration
	implements ModifiedDeclaration
{
	private final Adapter adapter;


	// ********** constructors **********

	public JDTModifiedDeclaration(Adapter adapter) {
		super();
		this.adapter = adapter;
	}

	public JDTModifiedDeclaration(BodyDeclaration declaration) {
		this(new BodyDeclarationAdapter(declaration));
	}
	
	public JDTModifiedDeclaration(PackageDeclaration declaration) {
		this(new PackageDeclarationAdapter(declaration));			
	}

	public JDTModifiedDeclaration(SingleVariableDeclaration declaration) {
		this(new SingleVariableDeclarationAdapter(declaration));
	}

	public JDTModifiedDeclaration(VariableDeclarationExpression declaration) {
		this(new VariableDeclarationExpressionAdapter(declaration));
	}

	public JDTModifiedDeclaration(VariableDeclarationStatement declaration) {
		this(new VariableDeclarationStatementAdapter(declaration));
	}


	// ********** annotations **********

	public Annotation getAnnotationNamed(String annotationName) {
		for (Annotation annotation : this.getAnnotations()) {
			if (this.annotationIsNamed(annotation, annotationName)) {
				return annotation;
			}
		}
		return null;
	}

	public void removeAnnotationNamed(String annotationName) {
		for (Iterator<IExtendedModifier> stream = this.getModifiers().iterator(); stream.hasNext(); ) {
			IExtendedModifier modifier = stream.next();
			if (modifier.isAnnotation()) {
				if (this.annotationIsNamed((Annotation) modifier, annotationName)) {
					stream.remove();
					break;
				}
			}
		}
	}

	public void replaceAnnotationNamed(String oldAnnotationName, Annotation newAnnotation) {
		List<IExtendedModifier> modifiers = this.getModifiers();
		for (ListIterator<IExtendedModifier> stream = modifiers.listIterator(); stream.hasNext(); ) {
			IExtendedModifier modifier = stream.next();
			if (modifier.isAnnotation()) {
				if (this.annotationIsNamed((Annotation) modifier, oldAnnotationName)) {
					stream.set(newAnnotation);
					return;
				}
			}
		}
		this.addAnnotation(newAnnotation);
	}

	/**
	 * Add the specified annotation to the declaration.
	 * By convention annotations precede the "standard" (JLS2) modifiers;
	 * though, technically, they can be interspersed.
	 */
	protected void addAnnotation(Annotation annotation) {
		List<IExtendedModifier> modifiers = this.getModifiers();
		for (ListIterator<IExtendedModifier> stream = modifiers.listIterator(); stream.hasNext(); ) {
			if (stream.next().isModifier()) {
				stream.previous();  // put the annotation *before* the first "standard" (JLS2) modifier
				stream.add(annotation);
				return;
			}
		}
		modifiers.add(annotation);  // just tack it on to the end
	}

	/**
	 * Return the declaration's annotations.
	 */
	protected Iterable<Annotation> getAnnotations() {
		return IterableTools.downCast(this.getAnnotations_());
	}

	protected Iterable<IExtendedModifier> getAnnotations_() {
		return IterableTools.filter(this.getModifiers(), EXTENDED_MODIFIER_IS_ANNOTATION);
	}

	protected static final Predicate<IExtendedModifier> EXTENDED_MODIFIER_IS_ANNOTATION = new ExtendedModifierIsAnnotation();
	protected static class ExtendedModifierIsAnnotation
		extends PredicateAdapter<IExtendedModifier>
	{
		@Override
		public boolean evaluate(IExtendedModifier modifier) {
			return modifier.isAnnotation();
		}
	}


	// ********** add import **********

	public boolean addImport(String className) {
		if (className.indexOf('.') == -1) {
			return true;  // the class is in the default package - no need for import
		}
		return this.addImport(className, false);
	}

	public boolean addStaticImport(String enumConstantName) {
		int index1 = enumConstantName.indexOf('.');
		if (index1 == -1) {
			throw new IllegalArgumentException(enumConstantName);  // shouldn't happen?
		}
		int index2 = enumConstantName.indexOf('.', index1 + 1);
		if (index2 == -1) {
			return true;  // the enum is in the default package - no need for import
		}
		return this.addImport(enumConstantName, true);
	}

	public boolean addImport(String importName, boolean staticImport) {
		Boolean include = this.importsInclude(importName, staticImport);
		if (include != null) {
			return include.booleanValue();
		}

		ImportDeclaration importDeclaration = this.getAst().newImportDeclaration();
		importDeclaration.setName(this.getAst().newName(importName));
		importDeclaration.setStatic(staticImport);
		this.getImports().add(importDeclaration);
		return true;
	}

	/**
	 * Just a bit hacky:
	 *     Return Boolean.TRUE if the import is already present.
	 *     Return Boolean.FALSE if a colliding import is already present.
	 *     Return null if a new import may be added.
	 * This hackery allows us to loop through the imports only once
	 * (and compose our methods).
	 * Pre-condition: 'importName' is not in the "default" package (i.e. it *is* qualified)
	 */
	protected Boolean importsInclude(String importName, boolean staticImport) {
		int period = importName.lastIndexOf('.');  // should not be -1
		String importNameQualifier = importName.substring(0, period);
		String shortImportName = importName.substring(period + 1);
		return this.importsInclude(importName, importNameQualifier, shortImportName, staticImport);
	}

	/**
	 * pre-calculate the qualifier and short name
	 */
	protected Boolean importsInclude(String importName, String importNameQualifier, String shortImportName, boolean staticImport) {
		for (ImportDeclaration importDeclaration : this.getImports()) {
			if (importDeclaration.isStatic() == staticImport) {
				Boolean match = this.importMatches(importDeclaration, importName, importNameQualifier, shortImportName);
				if (match != null) {
					return match;
				}
			}
		}
		return null;
	}

	/**
	 * we should be able to rely on the JDT model here, since we are looking
	 * at objects that should not be changing underneath us...
	 */
	protected Boolean importMatches(ImportDeclaration importDeclaration, String importName, String importNameQualifier, String shortImportName) {
		// examples:
		// 'importName' is "java.util.Date"
		//     or
		// 'importName' is "java.lang.annotation.ElementType.TYPE"
		String idn = importDeclaration.getName().getFullyQualifiedName();
		if (importName.equals(idn)) {
			// import java.util.Date; => "Date" will resolve to "java.util.Date"
			// import static java.lang.annotation.ElementType.TYPE; => "TYPE" will resolve to "java.lang.annotation.ElementType.TYPE"
			return Boolean.TRUE;
		}

		String shortIDN = idn.substring(idn.lastIndexOf('.') + 1);
		if (shortImportName.equals(shortIDN)) {
			// import java.sql.Date; => ambiguous resolution of "Date"
			// import static org.foo.Bar.TYPE; => ambiguous resolution of "TYPE"
			return Boolean.FALSE;
		}

		if (importDeclaration.isOnDemand()) {
			if (importNameQualifier.equals(idn)) {
				// import java.util.*; => "Date" will resolve to "java.util.Date"
				// import static java.lang.annotation.ElementType.*; => "TYPE" will resolve to "java.lang.annotation.ElementType.TYPE"
				return Boolean.TRUE;
			}
			if (importDeclaration.isStatic()) {
				if (this.enumResolves(idn, shortImportName)) {
					// import static org.foo.Bar.*; => ambiguous resolution of "TYPE"
					return Boolean.FALSE;
				}
			} else {
				if (this.typeResolves(idn + '.' + shortImportName)) {
					// import java.sql.*; => ambiguous resolution of "Date"
					return Boolean.FALSE;
				}
			}
		}
		// no matches - OK to add explicit import
		return null;
	}

	protected boolean enumResolves(String enumTypeName, String enumConstantName) {
		try {
			return this.enumResolves_(enumTypeName, enumConstantName);
		} catch (JavaModelException ex) {
			throw new RuntimeException(ex);
		}
	}

	protected boolean enumResolves_(String enumTypeName, String enumConstantName) throws JavaModelException {
		IType jdtType = this.findType_(enumTypeName);
		if (jdtType == null) {
			return false;
		}
		if ( ! jdtType.isEnum()) {
			return false;
		}
		for (IField jdtField : jdtType.getFields()) {
			if (jdtField.isEnumConstant() && jdtField.getElementName().equals(enumConstantName)) {
				return true;
			}
		}
		return false;
	}

	protected boolean typeResolves(String name) {
		return this.findType(name) != null;
	}

	protected IType findType(String name) {
		try {
			return this.findType_(name);
		} catch (JavaModelException ex) {
			throw new RuntimeException(ex);
		}
	}

	protected IType findType_(String name) throws JavaModelException {
		return this.getCompilationUnit().getJavaElement().getJavaProject().findType(name);
	}

	protected List<ImportDeclaration> getImports() {
		return this.imports(this.getCompilationUnit());
	}

	// minimize scope of suppressed warnings
	@SuppressWarnings("unchecked")
	protected List<ImportDeclaration> imports(CompilationUnit astRoot) {
		return astRoot.imports();
	}


	// ********** annotation name resolution **********

	public boolean annotationIsNamed(Annotation annotation, String name) {
		return this.getQualifiedName(annotation).equals(name);
	}

	/**
	 * Simply return the annotation's unqualified name if we can't "resolve" it.
	 */
	protected String getQualifiedName(Annotation annotation) {
		ITypeBinding typeBinding = annotation.resolveTypeBinding();
		if (typeBinding != null) {
			String resolvedName = typeBinding.getQualifiedName();
			if (resolvedName != null) {
				return resolvedName;
			}
		}
		// hack(?): check for a matching import because when moving a stand-alone
		// annotation to its container in CombinationIndexedDeclarationAnnotationAdapter
		// the container's import is added but then it won't "resolve" upon
		// subsequent lookups (because the parser hasn't had time to run?)... :-(
		return this.convertToFullClassName(annotation.getTypeName().getFullyQualifiedName());
	}

	/**
	 * If necessary, use the declaration's imports to calculate a guess as to
	 * the specified name's fully-qualified form.
	 * Simply return the unqualified name if we can't "resolve" it.
	 */
	protected String convertToFullClassName(String name) {
		// check for fully-qualified name
		return (name.lastIndexOf('.') != -1) ? name : this.resolveAgainstImports(name, false);
	}

	/**
	 * If necessary, use the declaration's imports to calculate a guess as to
	 * the specified name's fully-qualified form.
	 * Simply return the unqualified name if we can't "resolve" it.
	 */
	protected String convertToFullEnumConstantName(String name) {
		int index1 = name.indexOf('.');
		if (index1 == -1) {
			// short name, e.g. "TYPE"
			// true = look for static import of enum constant
			return this.resolveAgainstImports(name, true);
		}

		int index2 = name.indexOf('.', index1 + 1);
		if (index2 == -1) {
			// partially-qualified name, e.g. "ElementType.TYPE"
			// false = look regular import of enum class, not static import of enum constant
			return this.resolveAgainstImports(name, false);
		}

		// fully-qualified name, e.g. "java.lang.annotation.ElementType.TYPE"
		return name;
	}

	/**
	 * Attempt to resolve the specified "short" name against the declaration's
	 * imports. Return the name unchanged if we can't resolve it (perhaps it is
	 * in the "default" package).
	 */
	protected String resolveAgainstImports(String shortName, boolean static_) {
		for (ImportDeclaration importDeclaration : this.getImports()) {
			if (importDeclaration.isStatic() == static_) {
				String resolvedName = this.resolveAgainstImport(importDeclaration, shortName);
				if (resolvedName != null) {
					return resolvedName;
				}
			}
		}
		return shortName;  // "default" package or unknown
	}

	/**
	 * Attempt to resolve the specified "short" name against the specified
	 * import. Return the resolved name if the import resolves it; otherwise
	 * return null.
	 */
	protected String resolveAgainstImport(ImportDeclaration importDeclaration, String shortName) {
		String idn = importDeclaration.getName().getFullyQualifiedName();
		if (importDeclaration.isOnDemand()) {
			String candidate = idn + '.' + shortName;
			if (importDeclaration.isStatic()) {
				if (this.enumResolves(idn, shortName)) {
					return candidate;
				}
			} else {
				if (this.typeResolves(candidate)) {
					return candidate;
				}
			}
			// no match
			return null;
		}

		// explicit import - see whether its end matches 'shortName'
		int period = idn.length() - shortName.length() - 1;
		if (period < 1) {
			// something must precede period
			return null;
		}
		if ((idn.charAt(period) == '.') && idn.endsWith(shortName)) {
			return idn;  // probable exact match
		}
		return null;
	}


	// ********** miscellaneous methods **********

	public ASTNode getDeclaration() {
		return this.adapter.getDeclaration();
	}

	/**
	 * Return the declaration's list of modifiers.
	 * Element type: org.eclipse.jdt.core.dom.IExtendedModifier
	 */
	protected List<IExtendedModifier> getModifiers() {
		return this.adapter.getModifiers();
	}

	public AST getAst() {
		return this.getDeclaration().getAST();
	}

	protected CompilationUnit getCompilationUnit() {
		return (CompilationUnit) this.getDeclaration().getRoot();
	}

	@Override
	public String toString() {
		return ObjectTools.toString(this, this.adapter.toString());
	}


	// ********** declaration adapter interface and implementations **********

	/**
	 * Define common protocol among the various "declarations".
	 */
	public interface Adapter {

		/**
		 * Return the adapted "declaration".
		 */
		ASTNode getDeclaration();

		/**
		 * Return the "declaration"'s list of modifiers.
		 * Element type: org.eclipse.jdt.core.dom.IExtendedModifier
		 */
		List<IExtendedModifier> getModifiers();

	}

	public static class BodyDeclarationAdapter implements Adapter {
		private final BodyDeclaration declaration;
		public BodyDeclarationAdapter(BodyDeclaration declaration) {
			super();
			this.declaration = declaration;
		}
		public ASTNode getDeclaration() {
			return this.declaration;
		}
		@SuppressWarnings("unchecked")
		public List<IExtendedModifier> getModifiers() {
			return this.declaration.modifiers();
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, this.declaration.toString());
		}
	}
	
	public static class PackageDeclarationAdapter implements Adapter {
		private final PackageDeclaration declaration;
		public PackageDeclarationAdapter(PackageDeclaration declaration) {
			super();
			this.declaration = declaration;
		}
		public ASTNode getDeclaration() {
			return this.declaration;
		}
		@SuppressWarnings("unchecked")
		public List<IExtendedModifier> getModifiers() {
			return this.declaration.annotations();
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, this.declaration.toString());
		}
	}
	
	/*public static class ASTNodeAdapter implements Adapter {
		private final ASTNode declaration;
		public ASTNodeAdapter(ASTNode declaration) {
			super();
			this.declaration = declaration;
		}
		public ASTNode getDeclaration() {
			return this.declaration;
		}
		@SuppressWarnings("unchecked")
		public List<IExtendedModifier> getModifiers() {
			if (declaration instanceof BodyDeclaration) {
				return ((BodyDeclaration) declaration).modifiers();				
			} else if (declaration instanceof PackageDeclaration) {
				return ((PackageDeclaration) declaration).annotations();				
			}
			return Collections.emptyList();
		}
		@Override
		public String toString() {
			return Object_.toString(this, this.declaration.toString());
		}
	}*/

	public static class SingleVariableDeclarationAdapter implements Adapter {
		private final SingleVariableDeclaration declaration;
		public SingleVariableDeclarationAdapter(SingleVariableDeclaration declaration) {
			super();
			this.declaration = declaration;
		}
		public ASTNode getDeclaration() {
			return this.declaration;
		}
		@SuppressWarnings("unchecked")
		public List<IExtendedModifier> getModifiers() {
			return this.declaration.modifiers();
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, this.declaration.toString());
		}
	}

	public static class VariableDeclarationExpressionAdapter implements Adapter {
		private final VariableDeclarationExpression declaration;
		public VariableDeclarationExpressionAdapter(VariableDeclarationExpression declaration) {
			super();
			this.declaration = declaration;
		}
		public ASTNode getDeclaration() {
			return this.declaration;
		}
		@SuppressWarnings("unchecked")
		public List<IExtendedModifier> getModifiers() {
			return this.declaration.modifiers();
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, this.declaration.toString());
		}
	}

	public static class VariableDeclarationStatementAdapter implements Adapter {
		private final VariableDeclarationStatement declaration;
		public VariableDeclarationStatementAdapter(VariableDeclarationStatement declaration) {
			super();
			this.declaration = declaration;
		}
		public ASTNode getDeclaration() {
			return this.declaration;
		}
		@SuppressWarnings("unchecked")
		public List<IExtendedModifier> getModifiers() {
			return this.declaration.modifiers();
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, this.declaration.toString());
		}
	}

}
