/*******************************************************************************
 * 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.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.StringTools;
import org.eclipse.jpt.common.utility.internal.iterators.FilteringIterator;
import org.eclipse.jpt.common.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());
		}
	}

}
