/*******************************************************************************
 * Copyright (c) 2007, 2008 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.resource.java;

import java.util.Iterator;
import java.util.List;

import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jpt.core.JpaAnnotationProvider;
import org.eclipse.jpt.core.ResourceModelListener;
import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType;
import org.eclipse.jpt.core.resource.java.JpaCompilationUnit;
import org.eclipse.jpt.core.utility.TextRange;
import org.eclipse.jpt.core.utility.jdt.AnnotationEditFormatter;
import org.eclipse.jpt.utility.CommandExecutorProvider;
import org.eclipse.jpt.utility.internal.BitTools;
import org.eclipse.jpt.utility.internal.iterators.EmptyIterator;

/**
 * 
 */
public class JpaCompilationUnitImpl
	extends AbstractJavaResourceNode
	implements JpaCompilationUnit
{
	private final ICompilationUnit compilationUnit;

	private final JpaAnnotationProvider annotationProvider;

	private final CommandExecutorProvider modifySharedDocumentCommandExecutorProvider;

	private final AnnotationEditFormatter annotationEditFormatter;

	private final ResourceModelListener resourceModelListener;

	/**
	 * The primary type of the AST compilation unit. We are not going to handle
	 * multiple types defined in a single compilation unit. Entities must have
	 * a public/protected no-arg constructor, and there is no way to access
	 * the constructor in a package class (which is what all top-level,
	 * non-primary classes must be).
	 */
	protected JavaResourcePersistentType persistentType;	


	// ********** construction **********

	public JpaCompilationUnitImpl(
			ICompilationUnit compilationUnit,
			JpaAnnotationProvider annotationProvider, 
			CommandExecutorProvider modifySharedDocumentCommandExecutorProvider,
			AnnotationEditFormatter annotationEditFormatter,
			ResourceModelListener resourceModelListener) {
		super(null);  // the JPA compilation unit is the root of its sub-tree
		this.compilationUnit = compilationUnit;
		this.annotationProvider = annotationProvider;
		this.modifySharedDocumentCommandExecutorProvider = modifySharedDocumentCommandExecutorProvider;
		this.annotationEditFormatter = annotationEditFormatter;
		this.resourceModelListener = resourceModelListener;
		this.persistentType = this.buildPersistentType();
	}

	protected JavaResourcePersistentType buildPersistentType() {
		this.openCompilationUnit();
		CompilationUnit astRoot = this.buildASTRoot();
		this.closeCompilationUnit();
		return this.buildPersistentType(astRoot);
	}

	protected void openCompilationUnit() {
		try {
			this.compilationUnit.open(null);
		} catch (JavaModelException ex) {
			// do nothing - we just won't have a primary type in this case
		}
	}

	protected void closeCompilationUnit() {
		try {
			this.compilationUnit.close();
		} catch (JavaModelException ex) {
			// hmmm
		}
	}

	protected JavaResourcePersistentType buildPersistentType(CompilationUnit astRoot) {
		TypeDeclaration td = this.getPrimaryType(astRoot);
		return (td == null) ? null : this.buildPersistentType(astRoot, td);
	}

	public void initialize(CompilationUnit astRoot) {
		// never called?
	}


	// ********** AbstractJavaResourceNode overrides **********

	@Override
	protected boolean requiresParent() {
		return false;
	}

	@Override
	public JpaCompilationUnit getJpaCompilationUnit() {
		return this;
	}

	@Override
	public JpaAnnotationProvider getAnnotationProvider() {
		return this.annotationProvider;
	}
	

	// ********** JavaResourceNode implementation **********

	public void update(CompilationUnit astRoot) {
		TypeDeclaration td = this.getPrimaryType(astRoot);
		if (td == null) {
			this.persistentType = null;
		} else {
			if (this.persistentType == null) {
				this.persistentType = this.buildPersistentType(astRoot, td);
			} else {
				this.persistentType.update(astRoot);
			}
		}
	}

	public TextRange getTextRange(CompilationUnit astRoot) {
		return null;
	}


	// ********** JpaCompilationUnit implementation **********

	public ICompilationUnit getCompilationUnit() {
		return this.compilationUnit;
	}
	
	public Iterator<JavaResourcePersistentType> persistableTypes() {
		return (this.persistentType == null) ?
				EmptyIterator.<JavaResourcePersistentType>instance() :
				this.persistentType.allPersistableTypes();
	}

	public void resourceModelChanged() {
		this.resourceModelListener.resourceModelChanged();
	}

	public void resolveTypes() {
		if (this.persistentType != null) {
			this.persistentType.resolveTypes(this.buildASTRoot());
		}
	}

	public CommandExecutorProvider getModifySharedDocumentCommandExecutorProvider() {
		return this.modifySharedDocumentCommandExecutorProvider;
	}
	
	public AnnotationEditFormatter getAnnotationEditFormatter()  {
		return this.annotationEditFormatter;
	}
	

	// ********** Java changes **********

	public void javaElementChanged(ElementChangedEvent event) {
		this.synchWithJavaDelta(event.getDelta());
	}

	protected void synchWithJavaDelta(IJavaElementDelta delta) {
		switch (delta.getElement().getElementType()) {
			case IJavaElement.JAVA_PROJECT :
				if (this.classpathHasChanged(delta)) {
					this.updateFromJava();
					break;  // no need to check further
				}
			case IJavaElement.JAVA_MODEL :
			case IJavaElement.PACKAGE_FRAGMENT_ROOT :
			case IJavaElement.PACKAGE_FRAGMENT :
				this.synchChildrenWithJavaDelta(delta);
				break;
			case IJavaElement.COMPILATION_UNIT :
				if (this.deltaIsRelevant(delta)) {
					this.updateFromJava();
				}
				break;
			default :
				break; // the element type is somehow held by a compilation unit (i.e. probably doesn't happen)
		}
	}

	protected void synchChildrenWithJavaDelta(IJavaElementDelta delta) {
		for (IJavaElementDelta child : delta.getAffectedChildren()) {
			this.synchWithJavaDelta(child); // recurse
		}
	}

	// 235384 - We need to update all compilation units when a classpath change occurs.
	// The persistence.jar could have been added to or removed from the
	// classpath which affects whether we know about the JPA annotations.
	protected boolean classpathHasChanged(IJavaElementDelta delta) {
		return BitTools.anyFlagsAreSet(delta.getFlags(), this.getClasspathChangedFlags());
	}

	protected int getClasspathChangedFlags() {
		return CLASSPATH_CHANGED_FLAGS;
	}

	protected static final int CLASSPATH_CHANGED_FLAGS =
			IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED |
			IJavaElementDelta.F_CLASSPATH_CHANGED;

	protected boolean deltaIsRelevant(IJavaElementDelta delta) {
		// ignore changes to/from primary working copy - no content has changed;
		// and make sure there are no other flags set that indicate *both* a
		// change to/from primary working copy *and* content has changed
		if (BitTools.onlyFlagIsSet(delta.getFlags(), IJavaElementDelta.F_PRIMARY_WORKING_COPY)) {
			return false;
		}

		// we get the java notification for removal before we get the resource notification;
		// we do not need to handle this event and will get exceptions building an astRoot if we try
		if (delta.getKind() == IJavaElementDelta.REMOVED) {
			return false;
		}

		return delta.getElement().equals(this.compilationUnit);
	}

	protected void updateFromJava() {
		this.update(this.buildASTRoot());
	}


	// ********** internal **********

	protected CompilationUnit buildASTRoot() {
		return JDTTools.buildASTRoot(this.compilationUnit);
	}

	protected JavaResourcePersistentType buildPersistentType(CompilationUnit astRoot, TypeDeclaration typeDeclaration) {
		return JavaResourcePersistentTypeImpl.newInstance(this, typeDeclaration, astRoot);
	}

	/**
	 * i.e. the type with the same name as the compilation unit;
	 * return the first class or interface (ignore annotations and enums) with
	 * the same name as the compilation unit (file);
	 * NB: this type could be in error if there is an annotation or enum
	 * with the same name preceding it in the compilation unit
	 * 
	 * Return null if resolveBinding() on the TypeDeclaration returns null
	 * This can occur if the project JRE is removed (bug 225332)
	 */
	protected TypeDeclaration getPrimaryType(CompilationUnit astRoot) {
		String primaryTypeName = this.getPrimaryTypeName();
		for (AbstractTypeDeclaration atd : types(astRoot)) {
			if ((atd.getNodeType() == ASTNode.TYPE_DECLARATION)
					&& atd.getName().getFullyQualifiedName().equals(primaryTypeName)) {
				return (atd.resolveBinding()) != null ? (TypeDeclaration) atd : null;
			}
		}
		return null;
	}

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

	/**
	 * i.e. the name of the compilation unit
	 */
	protected String getPrimaryTypeName() {
		return removeJavaExtension(this.compilationUnit.getElementName());
	}

	protected static String removeJavaExtension(String fileName) {
		int index = fileName.lastIndexOf(".java"); //$NON-NLS-1$
		return (index == -1) ? fileName : fileName.substring(0, index);
	}

	@Override
	public void toString(StringBuilder sb) {
		sb.append(this.persistentType.getName());
	}

}
