/*******************************************************************************
 * 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.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.ListIterator;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jpt.core.internal.utility.jdt.ASTNodeTextRange;
import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
import org.eclipse.jpt.core.resource.java.Annotation;
import org.eclipse.jpt.core.resource.java.ContainerAnnotation;
import org.eclipse.jpt.core.resource.java.JavaResourceNode;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentMember;
import org.eclipse.jpt.core.resource.java.NestableAnnotation;
import org.eclipse.jpt.core.utility.TextRange;
import org.eclipse.jpt.core.utility.jdt.Member;
import org.eclipse.jpt.utility.MethodSignature;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator;
import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
import org.eclipse.jpt.utility.internal.iterators.SingleElementListIterator;

public abstract class AbstractJavaResourcePersistentMember<E extends Member>
	extends AbstractJavaResourceNode
	implements JavaResourcePersistentMember
{	
	private final E member;

	/**
	 * stores all annotations(non-mapping) except duplicates, java compiler has an error for duplicates
	 */
	private final Collection<Annotation> annotations;
	
	/**
	 * stores all mapping annotations except duplicates, java compiler has an error for duplicates
	 */
	private final Collection<Annotation> mappingAnnotations;
	
	private boolean persistable;

	AbstractJavaResourcePersistentMember(JavaResourceNode parent, E member){
		super(parent);
		this.member = member;
		this.annotations = new ArrayList<Annotation>();
		this.mappingAnnotations = new ArrayList<Annotation>();
	}

	public void initialize(CompilationUnit astRoot) {
		getMember().getBodyDeclaration(astRoot).accept(this.buildInitialAnnotationVisitor(astRoot));
		this.persistable = buildPersistable(astRoot);		
	}

	protected ASTVisitor buildInitialAnnotationVisitor(CompilationUnit astRoot) {
		return new LocalASTVisitor(astRoot, this.getMember().getBodyDeclaration(astRoot)) {
			@Override
			protected void visitChildAnnotation(org.eclipse.jdt.core.dom.Annotation node) {
				AbstractJavaResourcePersistentMember.this.addInitialAnnotation(node, this.astRoot);
			}
		};
	}
	
	protected void addInitialAnnotation(org.eclipse.jdt.core.dom.Annotation node, CompilationUnit astRoot) {
		String qualifiedAnnotationName = JDTTools.resolveAnnotation(node);
		if (qualifiedAnnotationName == null) {
			return;
		}
		if (isPossibleAnnotation(qualifiedAnnotationName)) {
			if (getAnnotation(qualifiedAnnotationName) == null) { //don't want duplicates
				Annotation annotation = buildAnnotation(qualifiedAnnotationName);
				annotation.initialize(astRoot);
				this.annotations.add(annotation);
			}
		}
		else if (isPossibleMappingAnnotation(qualifiedAnnotationName)) {
			if (getMappingAnnotation(qualifiedAnnotationName) == null) { //don't want duplicates
				Annotation annotation = buildMappingAnnotation(qualifiedAnnotationName);
				annotation.initialize(astRoot);
				this.mappingAnnotations.add(annotation);
			}
		}
	}

	public E getMember() {
		return this.member;
	}
	
	protected abstract Annotation buildAnnotation(String annotationName);
	
	protected abstract Annotation buildNullAnnotation(String annotationName);

	protected abstract Annotation buildMappingAnnotation(String mappingAnnotationName);
	
	protected abstract Annotation buildNullMappingAnnotation(String annotationName);

	protected abstract ListIterator<String> possibleMappingAnnotationNames();

	protected abstract boolean isPossibleAnnotation(String annotationName);
	
	protected abstract boolean isPossibleMappingAnnotation(String annotationName);
	
	protected boolean buildPersistable(CompilationUnit astRoot) {
		return this.getMember().isPersistable(astRoot);
	}


	public Annotation getAnnotation(String annotationName) {
		for (Iterator<Annotation> i = annotations(); i.hasNext(); ) {
			Annotation annotation = i.next();
			if (annotation.getAnnotationName().equals(annotationName)) {
				return annotation;
			}
		}
		return null;
	}
	
	public JavaResourceNode getNonNullAnnotation(String annotationName) {
		Annotation annotation = getAnnotation(annotationName);
		if (annotation == null) {
			return buildNullAnnotation(annotationName);	
		}
		return annotation;
	}
	
	public Annotation getMappingAnnotation(String annotationName) {
		for (Iterator<Annotation> i = mappingAnnotations(); i.hasNext(); ) {
			Annotation mappingAnnotation = i.next();
			if (mappingAnnotation.getAnnotationName().equals(annotationName)) {
				return mappingAnnotation;
			}
		}
		return null;
	}

	public JavaResourceNode getNullMappingAnnotation(String annotationName) {
		return buildNullMappingAnnotation(annotationName);	
	}
	
	@SuppressWarnings("unchecked")
	public Iterator<Annotation> annotations() {
		return new CloneIterator<Annotation>(this.annotations);
	}
	
	public int annotationsSize() {
		return this.annotations.size();
	}
	
	public Annotation addAnnotation(String annotationName) {
		Annotation annotation = buildAnnotation(annotationName);
		this.annotations.add(annotation);
		annotation.newAnnotation();
		this.fireItemAdded(ANNOTATIONS_COLLECTION, annotation);
		return annotation;
	}

	@SuppressWarnings("unchecked")
	protected ContainerAnnotation<NestableAnnotation> addContainerAnnotation(String containerAnnotationName) {
		return (ContainerAnnotation<NestableAnnotation>) addAnnotation(containerAnnotationName);
	}
	
	protected ContainerAnnotation<NestableAnnotation> addContainerAnnotationTwoNestableAnnotations(String containerAnnotationName) {
		ContainerAnnotation<NestableAnnotation> containerAnnotation = buildContainerAnnotation(containerAnnotationName);
		this.annotations.add(containerAnnotation);
		containerAnnotation.newAnnotation();
		containerAnnotation.addInternal(0).newAnnotation();
		containerAnnotation.addInternal(1).newAnnotation();
		return containerAnnotation;
	}
		
	@SuppressWarnings("unchecked")
	protected ContainerAnnotation<NestableAnnotation>  buildContainerAnnotation(String containerAnnotationName) {
		return (ContainerAnnotation<NestableAnnotation>) buildAnnotation(containerAnnotationName);
	}
	
	@SuppressWarnings("unchecked")
	protected ContainerAnnotation<NestableAnnotation> getContainerAnnotation(String containerAnnotationName) {
		return (ContainerAnnotation<NestableAnnotation>) getAnnotation(containerAnnotationName);
	}
	
	protected NestableAnnotation getNestableAnnotation(String nestableAnnotationName) {
		return (NestableAnnotation) getAnnotation(nestableAnnotationName);
	}
	
	protected NestableAnnotation addNestableAnnotation(String nestableAnnotationName) {
		return (NestableAnnotation) addAnnotation(nestableAnnotationName);
	}
	
	//TODO it seems we should be firing one change notification here, that a new nestable annotation was added.
	public NestableAnnotation addAnnotation(int index, String nestableAnnotationName, String containerAnnotationName) {
		NestableAnnotation nestedAnnotation = (NestableAnnotation) getAnnotation(nestableAnnotationName);
		
		ContainerAnnotation<NestableAnnotation> containerAnnotation = getContainerAnnotation(containerAnnotationName);
		
		if (containerAnnotation != null) {
			//ignore any nestableAnnotation and just add to the plural one
			NestableAnnotation newNestedAnnotation = ContainerAnnotationTools.addNestedAnnotation(index, containerAnnotation);
			//TODO any event notification being fired for the add???
			return newNestedAnnotation;
		}
		if (nestedAnnotation == null) {
			//add the nestable since neither nestable or container exists
			return addNestableAnnotation(nestableAnnotationName);
		}
		//move the nestable to a new container annotation and add to it
		ContainerAnnotation<NestableAnnotation> newContainerAnnotation = addContainerAnnotationTwoNestableAnnotations(containerAnnotationName);
		if (index == 0) {
			newContainerAnnotation.nestedAnnotationAt(1).initializeFrom(nestedAnnotation);
		}
		else {
			newContainerAnnotation.nestedAnnotationAt(0).initializeFrom(nestedAnnotation);		
		}
		removeAnnotation(nestedAnnotation);
		return newContainerAnnotation.nestedAnnotationAt(index);
	}
	
	public void move(int targetIndex, int sourceIndex, String containerAnnotationName) {
		move(targetIndex, sourceIndex, getContainerAnnotation(containerAnnotationName));
	}
	
	protected void move(int targetIndex, int sourceIndex, ContainerAnnotation<NestableAnnotation> containerAnnotation) {
		containerAnnotation.move(targetIndex, sourceIndex);
		ContainerAnnotationTools.synchAnnotationsAfterMove(targetIndex, sourceIndex, containerAnnotation);
	}
	
	protected void addAnnotation(Annotation annotation) {
		addItemToCollection(annotation, this.annotations, ANNOTATIONS_COLLECTION);
	}
	
	protected void removeAnnotation(Annotation annotation) {
		removeAnnotation_(annotation);
		//TODO looks odd that we remove the annotation here, but in addAnnotation(Annotation) we don't do the same
		annotation.removeAnnotation();
	}
	
	protected void removeAnnotation_(Annotation annotation) {
		removeItemFromCollection(annotation, this.annotations, ANNOTATIONS_COLLECTION);
	}
	
	protected void addMappingAnnotation(String mappingAnnotationName) {
		if (getMappingAnnotation(mappingAnnotationName) != null) {
			return;
		}
		Annotation mappingAnnotation = buildMappingAnnotation(mappingAnnotationName);
		addMappingAnnotation(mappingAnnotation);
		//TODO should this be done here or should creating the Annotation do this??
		mappingAnnotation.newAnnotation();
	}	

	protected void addMappingAnnotation(Annotation annotation) {
		addItemToCollection(annotation, this.mappingAnnotations, MAPPING_ANNOTATIONS_COLLECTION);
	}
	
	protected void removeMappingAnnotation(Annotation annotation) {
		removeMappingAnnotation_(annotation);
		annotation.removeAnnotation();
	}
	
	protected void removeMappingAnnotation_(Annotation annotation) {
		removeItemFromCollection(annotation, this.mappingAnnotations, MAPPING_ANNOTATIONS_COLLECTION);
	}
	
	@SuppressWarnings("unchecked")
	public Iterator<Annotation> mappingAnnotations() {
		return new CloneIterator<Annotation>(this.mappingAnnotations);
	}

	public int mappingAnnotationsSize() {
		return this.mappingAnnotations.size();
	}
	
	public void removeAnnotation(String annotationName) {
		Annotation annotation = getAnnotation(annotationName);
		if (annotation != null) {
			removeAnnotation(annotation);
		}
	}
	
	public void removeAnnotation(int index, String nestableAnnotationName, String containerAnnotationName) {
		ContainerAnnotation<NestableAnnotation> containerAnnotation = getContainerAnnotation(containerAnnotationName);
		if (containerAnnotation == null) {
			Annotation annotation = getAnnotation(nestableAnnotationName);
			removeAnnotation(annotation);
		}
		else {
			removeAnnotation(index, containerAnnotation);
		}
	}
	
	protected void removeAnnotation(int index, ContainerAnnotation<NestableAnnotation> containerAnnotation) {
		NestableAnnotation nestableAnnotation = containerAnnotation.nestedAnnotationAt(index);
		containerAnnotation.remove(index);
		//TODO move these 2 lines to the ContainerAnnotation implementation, i think
		nestableAnnotation.removeAnnotation();
		ContainerAnnotationTools.synchAnnotationsAfterRemove(index, containerAnnotation);
		
		if (containerAnnotation.nestedAnnotationsSize() == 0) {
			removeAnnotation(containerAnnotation);
		}
		else if (containerAnnotation.nestedAnnotationsSize() == 1) {
			NestableAnnotation nestedAnnotation = containerAnnotation.nestedAnnotationAt(0);
			
			this.annotations.remove(containerAnnotation);
			containerAnnotation.removeAnnotation();


			NestableAnnotation newAnnotation = (NestableAnnotation) buildAnnotation(containerAnnotation.getNestableAnnotationName());
			this.annotations.add(newAnnotation);
			newAnnotation.newAnnotation();

			newAnnotation.initializeFrom(nestedAnnotation);
			
			this.fireItemAdded(ANNOTATIONS_COLLECTION, newAnnotation);
			fireItemRemoved(ANNOTATIONS_COLLECTION, containerAnnotation);
		}
	}
	// removes all other *mapping* annotations that exist, not just the one returned by mappingAnnotation()
	// mappingAnnotation() returns the first mapping annotation found in the source.  if there are multiple
	// mapping annotations (which is a validation error condition) then calling this api would not work
	// because the new mapping annotatio would be added to the end of the list of annotations.
	public void setMappingAnnotation(String annotationName) {
		if (getMappingAnnotation(annotationName) != null) {
			throw new IllegalStateException("The mapping annotation named " + annotationName + " already exists.");
		}
		Annotation oldMapping = getMappingAnnotation();
		Annotation newMapping = null;
		if (oldMapping != null) {
			removeUnnecessaryAnnotations(annotationName);
		}
		if (annotationName != null) {
			if (getMappingAnnotation(annotationName) != null) {
				return;
			}
			newMapping = buildMappingAnnotation(annotationName);
			this.mappingAnnotations.add(newMapping);
			newMapping.newAnnotation();
		}
		//have to hold property change notification until the end so a project update does not occur
		//before we are finished removing the old mapping and adding the new mapping
		//just firing collectio changed since one or more removes and one add was completed.
		//if we ever listen for specific events instead of just doing a mass update, we might need to make this more specific
		fireCollectionChanged(MAPPING_ANNOTATIONS_COLLECTION);
	}
	/**
	 * Remove all mapping annotations that already exist.
	 * No change notification fired.
	 */
	protected void removeUnnecessaryAnnotations(String newMappingAnnotationName) {	
		for (ListIterator<String> i = possibleMappingAnnotationNames(); i.hasNext(); ) {
			String mappingAnnotationName = i.next();
			if (mappingAnnotationName != newMappingAnnotationName) {
				Annotation mappingAnnotation = getMappingAnnotation(mappingAnnotationName);
				if (mappingAnnotation != null) {
					this.mappingAnnotations.remove(mappingAnnotation);
					mappingAnnotation.removeAnnotation();
				}
			}
		}
	}
	
	//TODO need property change notification on this mappingAnnotation changing
	//from the context model we don't really care if their are multiple mapping annotations,
	//just which one we need to use
	public Annotation getMappingAnnotation() {
		for (ListIterator<String> i = possibleMappingAnnotationNames(); i.hasNext(); ) {
			String mappingAnnotationName = i.next();
			for (Iterator<Annotation> j = mappingAnnotations(); j.hasNext(); ) {
				Annotation mappingAnnotation = j.next();
				if (mappingAnnotationName == mappingAnnotation.getAnnotationName()) {
					return mappingAnnotation;
				}
			}
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public ListIterator<NestableAnnotation> annotations(String nestableAnnotationName, String containerAnnotationName) {
		ContainerAnnotation<NestableAnnotation> containerAnnotation = getContainerAnnotation(containerAnnotationName);
		if (containerAnnotation != null) {
			return containerAnnotation.nestedAnnotations();
		}
		NestableAnnotation nestableAnnotation = getNestableAnnotation(nestableAnnotationName);
		if (nestableAnnotation != null) {
			return new SingleElementListIterator<NestableAnnotation>(nestableAnnotation);
		}
		return EmptyListIterator.instance();
	}
	
	public void update(CompilationUnit astRoot) {
		this.updateAnnotations(astRoot);
		this.setPersistable(this.buildPersistable(astRoot));		
	}
	
	public void resolveTypes(CompilationUnit astRoot) {
		this.setPersistable(this.buildPersistable(astRoot));		
	}
	
	protected void updateAnnotations(CompilationUnit astRoot) {
		getMember().getBodyDeclaration(astRoot).accept(this.buildUpdateAnnotationVisitor(astRoot));
		removeMappingAnnotationsNotInSource(astRoot);
		removeAnnotationsNotInSource(astRoot);
	}
	
	protected void removeAnnotationsNotInSource(CompilationUnit astRoot) {
		for (Annotation annotation : CollectionTools.iterable(annotations())) {
			if (annotation.getJdtAnnotation(astRoot) == null) {
				removeAnnotation_(annotation);
			}
		}		
	}
	
	protected void removeMappingAnnotationsNotInSource(CompilationUnit astRoot) {
		for (Annotation mappingAnnotation : CollectionTools.iterable(mappingAnnotations())) {
			if (mappingAnnotation.getJdtAnnotation(astRoot) == null) {
				removeMappingAnnotation_(mappingAnnotation);
			}
		}	
	}
	
	protected ASTVisitor buildUpdateAnnotationVisitor(CompilationUnit astRoot) {
		return new LocalASTVisitor(astRoot, this.getMember().getBodyDeclaration(astRoot)) {
			@Override
			protected void visitChildAnnotation(org.eclipse.jdt.core.dom.Annotation node) {
				AbstractJavaResourcePersistentMember.this.addOrUpdateAnnotation(node, this.astRoot);
			}
		};
	}
	
	protected void addOrUpdateAnnotation(org.eclipse.jdt.core.dom.Annotation node, CompilationUnit astRoot) {
		String qualifiedAnnotationName = JDTTools.resolveAnnotation(node);
		if (qualifiedAnnotationName == null) {
			return;
		}
		if (isPossibleAnnotation(qualifiedAnnotationName)) {
			Annotation annotation = getAnnotation(qualifiedAnnotationName);
			if (annotation != null) {
				annotation.update(astRoot);
			}
			else {
				annotation = buildAnnotation(qualifiedAnnotationName);
				annotation.initialize(astRoot);
				addAnnotation(annotation);				
			}
		}
		else if (isPossibleMappingAnnotation(qualifiedAnnotationName)) {
			Annotation annotation = getMappingAnnotation(qualifiedAnnotationName);
			if (annotation != null) {
				annotation.update(astRoot);
			}
			else {
				annotation = buildMappingAnnotation(qualifiedAnnotationName);
				annotation.initialize(astRoot);
				addMappingAnnotation(annotation);				
			}
		}
	}

	public boolean isFor(String memberName, int occurrence) {
		return this.member.matches(memberName, occurrence);
	}

	public boolean isFor(MethodSignature methodSignature, int occurrence) {
		return false;
	}

	public boolean isPersistable() {
		return this.persistable;
	}
	
	protected void setPersistable(boolean newPersistable) {
		boolean oldPersistable = this.persistable;
		this.persistable = newPersistable;
		firePropertyChanged(PERSISTABLE_PROPERTY, oldPersistable, newPersistable);
		//TODO change notification to parent so that the context model gets notification 
		//that the list of persistable fields has been updated
		//
	}
	
	public boolean isPersisted() {
		return getMappingAnnotation() != null;
	}

	public TextRange fullTextRange(CompilationUnit astRoot) {
		return this.getTextRange(this.getMember().getBodyDeclaration(astRoot));
	}

	public TextRange getTextRange(CompilationUnit astRoot) {
		return this.fullTextRange(astRoot);
	}

	public TextRange getNameTextRange(CompilationUnit astRoot) {
		return this.getMember().getNameTextRange(astRoot);
	}
	
	protected TextRange getTextRange(ASTNode astNode) {
		return (astNode == null) ? null : new ASTNodeTextRange(astNode);
	}

	protected static <T extends JavaResourcePersistentMember> Iterator<T> persistableMembers(Iterator<T> attributes) {
		return new FilteringIterator<T, T>(attributes) {
			@Override
			protected boolean accept(T attribute) {
				return attribute.isPersistable();
			}
		};
	}

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


	// ********** AST visitor **********

	protected abstract class LocalASTVisitor extends ASTVisitor {
		protected final CompilationUnit astRoot;
		protected final BodyDeclaration bodyDeclaration;

		protected LocalASTVisitor(CompilationUnit astRoot, BodyDeclaration bodyDeclaration) {
			super();
			this.astRoot = astRoot;
			this.bodyDeclaration = bodyDeclaration;
		}

		@Override
		public boolean visit(SingleMemberAnnotation node) {
			return visit_(node);
		}
	
		@Override
		public boolean visit(NormalAnnotation node) {
			return visit_(node);
		}
	
		@Override
		public boolean visit(MarkerAnnotation node) {
			return visit_(node);
		}
		
		protected boolean visit_(org.eclipse.jdt.core.dom.Annotation node) {
			// ignore annotations for child members, only this member
			if (node.getParent() == this.bodyDeclaration) {
				this.visitChildAnnotation(node);
			}
			return false;
		}

		protected abstract void visitChildAnnotation(org.eclipse.jdt.core.dom.Annotation node);

	}
	
}
