/*******************************************************************************
 * Copyright (c) 2006, 2010 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.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.core.utility.jdt.ModifiedDeclaration;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
import org.eclipse.jpt.utility.internal.iterators.SubIteratorWrapper;

/**
 * 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 (Iterator<Annotation> stream = this.annotations(); stream.hasNext(); ) {
			Annotation annotation = stream.next();
			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 Iterator<Annotation> annotations() {
		return new SubIteratorWrapper<IExtendedModifier, Annotation>(this.annotations_());
	}

	protected Iterator<IExtendedModifier> annotations_() {
		return new FilteringIterator<IExtendedModifier>(this.getModifiers().iterator()) {
			@Override
			protected boolean accept(IExtendedModifier next) {
				return next.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 StringTools.buildToStringFor(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 StringTools.buildToStringFor(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 StringTools.buildToStringFor(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 StringTools.buildToStringFor(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 StringTools.buildToStringFor(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 StringTools.buildToStringFor(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 StringTools.buildToStringFor(this, this.declaration.toString());
		}
	}

}
