/*******************************************************************************
 * 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.List;
import java.util.ListIterator;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jpt.core.internal.jdtutility.AnnotationEditFormatter;
import org.eclipse.jpt.core.internal.jdtutility.Attribute;
import org.eclipse.jpt.core.internal.jdtutility.FieldAttribute;
import org.eclipse.jpt.core.internal.jdtutility.JPTTools;
import org.eclipse.jpt.core.internal.jdtutility.MethodAttribute;
import org.eclipse.jpt.core.internal.jdtutility.Type;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.CommandExecutorProvider;
import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;

public class JavaPersistentTypeResourceImpl extends AbstractJavaPersistentResource<Type> implements JavaPersistentTypeResource
{	
	/**
	 * store all member types including those that aren't persistable so we can include validation errors.
	 */
	private final Collection<JavaPersistentTypeResource> nestedTypes;
	
	private final Collection<JavaPersistentAttributeResource> attributes;
	
	private AccessType accessType;
	
	private String superClassQualifiedName;
	
	private String qualifiedName;
	
	private String name;
	
	private boolean isAbstract;
	
	public JavaPersistentTypeResourceImpl(JavaResource parent, Type type){
		super(parent, type);
		this.nestedTypes = new ArrayList<JavaPersistentTypeResource>(); 
		this.attributes = new ArrayList<JavaPersistentAttributeResource>();
	}

	@Override
	public void initialize(CompilationUnit astRoot) {
		super.initialize(astRoot);
		this.qualifiedName = this.qualifiedName(astRoot);
		this.name = this.name(astRoot);
		this.initializeNestedTypes(astRoot);
		this.initializeAttributes(astRoot);
		this.accessType = this.calculateAccessType();
		this.superClassQualifiedName = this.superClassQualifiedName(astRoot);
		this.isAbstract = this.isAbstract(astRoot);
	}
	
	protected void initializeNestedTypes(CompilationUnit astRoot) {
		for (IType declaredType : getMember().declaredTypes()) {
			this.nestedTypes.add(createJavaPersistentType(declaredType, astRoot));
		}
	}
	
	protected void initializeAttributes(CompilationUnit astRoot) {
		for (IField field : getMember().fields()) {
			this.attributes.add(createJavaPersistentAttribute(field, astRoot));
		}
		for (IMethod method : getMember().methods()) {
			this.attributes.add(createJavaPersistentAttribute(method, astRoot));
		}
	}
	
	// ******** AbstractJavaPersistentResource implementation ********

	@Override
	protected Annotation buildMappingAnnotation(String mappingAnnotationName) {
		return annotationProvider().buildTypeMappingAnnotation(this, getMember(), mappingAnnotationName);
	}
	
	@Override
	protected Annotation buildNullMappingAnnotation(String annotationName) {
		return annotationProvider().buildNullTypeMappingAnnotation(this, getMember(), annotationName);
	}

	@Override
	protected Annotation buildAnnotation(String annotationName) {
		return annotationProvider().buildTypeAnnotation(this, getMember(), annotationName);
	}
	
	@Override
	protected Annotation buildNullAnnotation(String annotationName) {
		return annotationProvider().buildNullTypeAnnotation(this, getMember(), annotationName);
	}
	
	@Override
	protected ListIterator<String> possibleMappingAnnotationNames() {
		return annotationProvider().typeMappingAnnotationNames();
	}
	
	@Override
	protected boolean isPossibleAnnotation(String annotationName) {
		return CollectionTools.contains(annotationProvider().typeAnnotationNames(), annotationName);
	}
	
	@Override
	protected boolean isPossibleMappingAnnotation(String annotationName) {
		return CollectionTools.contains(annotationProvider().typeMappingAnnotationNames(), annotationName);
	}
	
	@Override
	protected boolean calculatePersistability(CompilationUnit astRoot) {
		return JPTTools.typeIsPersistable(getMember().binding(astRoot));
	}


	@Override
	@SuppressWarnings("unchecked")
	//overriding purely to suppress the warning you get at the class level
	public ListIterator<NestableAnnotation> annotations(String nestableAnnotationName, String containerAnnotationName) {
		return super.annotations(nestableAnnotationName, containerAnnotationName);
	}
	
	@Override
	@SuppressWarnings("unchecked")
	//overriding purely to suppress the warning you get at the class level
	public Iterator<Annotation> mappingAnnotations() {
		return super.mappingAnnotations();
	}
	
	@Override
	@SuppressWarnings("unchecked")
	//overriding purely to suppress the warning you get at the class level
	public Iterator<Annotation> annotations() {
		return super.annotations();
	}

	
	// ******** JavaPersistentTypeResource implementation ********
	public JavaPersistentTypeResource javaPersistentTypeResource(String fullyQualifiedTypeName) {
		if (getQualifiedName().equals(fullyQualifiedTypeName)) {
			return this;
		}
		for (JavaPersistentTypeResource jptr : CollectionTools.iterable(nestedTypes())) {
			if (jptr.getQualifiedName().equals(fullyQualifiedTypeName)) {
				return jptr;
			}
		}
		return null;
	}

	public Iterator<JavaPersistentTypeResource> nestedTypes() {
		//TODO since we are filtering how do we handle the case where a type becomes persistable?
		//what kind of change notificiation for that case?
		return new FilteringIterator<JavaPersistentTypeResource, JavaPersistentTypeResource>(new CloneIterator<JavaPersistentTypeResource>(this.nestedTypes)) {
			@Override
			protected boolean accept(JavaPersistentTypeResource o) {
				return o.isPersistable();
			}
		};
	}
	
	protected JavaPersistentTypeResource nestedTypeFor(IType type) {
		for (JavaPersistentTypeResource nestedType : this.nestedTypes) {
			if (nestedType.isFor(type)) {
				return nestedType;
			}
		}
		return null;
	}
	
	protected JavaPersistentTypeResource addNestedType(IType nestedType, CompilationUnit astRoot) {
		JavaPersistentTypeResource persistentType = createJavaPersistentType(nestedType, astRoot);
		addNestedType(persistentType);
		return persistentType;
	}

	protected void addNestedType(JavaPersistentTypeResource nestedType) {
		addItemToCollection(nestedType, this.nestedTypes, NESTED_TYPES_COLLECTION);
	}
	
	protected void removeNestedType(JavaPersistentTypeResource nestedType) {
		removeItemFromCollection(nestedType, this.nestedTypes, NESTED_TYPES_COLLECTION);
	}
	
	protected JavaPersistentTypeResource createJavaPersistentType(IType nestedType, CompilationUnit astRoot) {
		return createJavaPersistentType(this, nestedType, modifySharedDocumentCommandExecutorProvider(), annotationEditFormatter(), astRoot);
	}

	public static JavaPersistentTypeResource createJavaPersistentType(
		JavaResource parent, 
		IType nestedType, 
		CommandExecutorProvider modifySharedDocumentCommandExecutorProvider,
		AnnotationEditFormatter annotationEditFormatter, 
		CompilationUnit astRoot) {
		
		Type type = new Type(nestedType, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
		JavaPersistentTypeResourceImpl javaPersistentType = new JavaPersistentTypeResourceImpl(parent, type);
		javaPersistentType.initialize(astRoot);
		return javaPersistentType;	
	}
	
	public Iterator<JavaPersistentAttributeResource> attributes() {
		//TODO since we are filtering how do we handle the case where an attribute becomes persistable?
		//what kind of change notificiation for that case?
		return new FilteringIterator<JavaPersistentAttributeResource, JavaPersistentAttributeResource>(new CloneIterator<JavaPersistentAttributeResource>(this.attributes)) {
			@Override
			protected boolean accept(JavaPersistentAttributeResource o) {
				return o.isPersistable();
			}
		};
	}
	
	public Iterator<JavaPersistentAttributeResource> fields() {
		return new FilteringIterator<JavaPersistentAttributeResource, JavaPersistentAttributeResource>(attributes()) {
			@Override
			protected boolean accept(JavaPersistentAttributeResource o) {
				return o.isForField();
			}
		};
	}
	
	public Iterator<JavaPersistentAttributeResource> properties() {
		return new FilteringIterator<JavaPersistentAttributeResource, JavaPersistentAttributeResource>(attributes()) {
			@Override
			protected boolean accept(JavaPersistentAttributeResource o) {
				return o.isForProperty();
			}
		};
	}

	protected JavaPersistentAttributeResource addAttribute(IMember jdtMember, CompilationUnit astRoot) {
		JavaPersistentAttributeResource persistentAttribute = createJavaPersistentAttribute(jdtMember, astRoot);
		addAttribute(persistentAttribute);
		return persistentAttribute;
	}
	
	protected void addAttribute(JavaPersistentAttributeResource attribute) {
		addItemToCollection(attribute, this.attributes, ATTRIBUTES_COLLECTION);
	}

	protected JavaPersistentAttributeResource createJavaPersistentAttribute(IMember member, CompilationUnit astRoot) {
		Attribute attribute = null;
		if (member instanceof IField) {
			attribute = new FieldAttribute((IField) member, this.modifySharedDocumentCommandExecutorProvider(), this.annotationEditFormatter());
		}
		else if (member instanceof IMethod) {
			attribute = new MethodAttribute((IMethod) member, this.modifySharedDocumentCommandExecutorProvider(), this.annotationEditFormatter());
		}
		else {
			throw new IllegalArgumentException();
		}
		JavaPersistentAttributeResource javaPersistentAttribute = new JavaPersistentAttributeResourceImpl(this, attribute);
		javaPersistentAttribute.initialize(astRoot);
		return javaPersistentAttribute;
	}
	
	protected void removeAttribute(JavaPersistentAttributeResource attribute) {
		removeItemFromCollection(attribute, this.attributes, ATTRIBUTES_COLLECTION);
	}
	
	protected JavaPersistentAttributeResource attributeFor(IMember member) {
		for (JavaPersistentAttributeResource persistentAttribute : this.attributes) {
			if (persistentAttribute.isFor(member)) {
				return persistentAttribute;
			}
		}
		return null;
	}
	
	public AccessType getAccess() {
		return this.accessType;
	}
	
	//seems we could have a public changeAccess() api which would
	//move all annotations from fields to their corresponding methods or vice versa
	//though of course it's more complicated than that since what if the
	//corresponding field/method does not exist?
	//making this internal since it should only be set based on changes in the source, the
	//context model should not need to set this
	protected void setAccess(AccessType newAccess) {
		AccessType oldAccess = this.accessType;
		this.accessType = newAccess;
		firePropertyChanged(ACCESS_PROPERTY, oldAccess, newAccess);
	}

	public String getSuperClassQualifiedName() {
		return this.superClassQualifiedName;
	}
	
	private void setSuperClassQualifiedName(String newSuperClassQualifiedName) {
		String oldSuperClassQualifiedName = this.superClassQualifiedName;
		this.superClassQualifiedName = newSuperClassQualifiedName;
		firePropertyChanged(SUPER_CLASS_QUALIFIED_NAME_PROPERTY, oldSuperClassQualifiedName, newSuperClassQualifiedName);
	}

	public String getQualifiedName() {
		return this.qualifiedName;
	}
	
	protected void setQualifiedName(String newQualifiedName) {
		String oldQualifiedName = this.qualifiedName;
		this.qualifiedName = newQualifiedName;
		firePropertyChanged(QUALIFIED_NAME_PROPERTY, oldQualifiedName, newQualifiedName);
	}
	
	public String getName() {
		return this.name;
	}
	
	protected void setName(String newName) {
		String oldName = this.name;
		this.name = newName;
		firePropertyChanged(NAME_PROPERTY, oldName, newName);
	}
	
	public boolean isAbstract() {
		return this.isAbstract;
	}
	
	protected void setAbstract(boolean newAbstract) {
		boolean oldAbstract = this.isAbstract;
		this.isAbstract = newAbstract;
		firePropertyChanged(ABSTRACT_PROPERTY, oldAbstract, newAbstract);
	}
	
	@Override
	public void updateFromJava(CompilationUnit astRoot) {
		super.updateFromJava(astRoot);
		this.setQualifiedName(this.qualifiedName(astRoot));
		this.setName(this.name(astRoot));
		this.updateNestedTypes(astRoot);
		this.updatePersistentAttributes(astRoot);
		this.setAccess(this.calculateAccessType());
		this.setSuperClassQualifiedName(this.superClassQualifiedName(astRoot));
		this.setAbstract(isAbstract(astRoot));
	}
	
	@Override
	public void resolveTypes(CompilationUnit astRoot) {
		super.resolveTypes(astRoot);
		for (JavaPersistentAttributeResource attribute : this.attributes) {
			attribute.resolveTypes(astRoot);
		}
		for (JavaPersistentTypeResource persistentType : this.nestedTypes) {
			persistentType.resolveTypes(astRoot);
		}
	}
	
	protected boolean isAbstract(CompilationUnit astRoot) {
		return JPTTools.typeIsAbstract(getMember().binding(astRoot));
	}

	protected String qualifiedName(CompilationUnit astRoot) {
		return getMember().binding(astRoot).getQualifiedName();
	}
	
	protected String name(CompilationUnit astRoot) {
		return getMember().binding(astRoot).getName();
	}
	
	protected void updateNestedTypes(CompilationUnit astRoot) {
		IType[] declaredTypes = getMember().declaredTypes();
		
		List<JavaPersistentTypeResource> nestedTypesToRemove = new ArrayList<JavaPersistentTypeResource>(this.nestedTypes);
		for (IType declaredType : declaredTypes) {
			JavaPersistentTypeResource nestedType = nestedTypeFor(declaredType);
			if (nestedType == null) {
				nestedType = addNestedType(declaredType, astRoot);
			}
			else {
				nestedTypesToRemove.remove(nestedType);
			}
			nestedType.updateFromJava(astRoot);
		}
		for (JavaPersistentTypeResource nestedType : nestedTypesToRemove) {
			removeNestedType(nestedType);
		}
	}
	
	protected void updatePersistentAttributes(CompilationUnit astRoot) {
		List<JavaPersistentAttributeResource> persistentAttributesToRemove = new ArrayList<JavaPersistentAttributeResource>(this.attributes);
		updatePersistentFields(astRoot, persistentAttributesToRemove);
		updatePersistentProperties(astRoot, persistentAttributesToRemove);
		for (JavaPersistentAttributeResource persistentAttribute : persistentAttributesToRemove) {
			removeAttribute(persistentAttribute);
		}
	}
	
	protected void updatePersistentFields(CompilationUnit astRoot, List<JavaPersistentAttributeResource> persistentAttributesToRemove) {
		updatePersistentAttributes(astRoot, persistentAttributesToRemove, getMember().fields());
	}

	protected void updatePersistentProperties(CompilationUnit astRoot, List<JavaPersistentAttributeResource> persistentAttributesToRemove) {
		updatePersistentAttributes(astRoot, persistentAttributesToRemove, getMember().methods());
	}

	protected void updatePersistentAttributes(CompilationUnit astRoot, List<JavaPersistentAttributeResource> persistentAttributesToRemove, IMember[] members) {
		for (IMember member : members) {
			JavaPersistentAttributeResource persistentAttribute = attributeFor(member);
			if (persistentAttribute == null) {
				persistentAttribute = addAttribute(member, astRoot);
			}
			else {
				persistentAttributesToRemove.remove(persistentAttribute);
			}
			persistentAttribute.updateFromJava(astRoot);
		}
	}
	
	public boolean hasAnyAttributeAnnotations() {
		for (JavaPersistentAttributeResource attribute : CollectionTools.iterable(attributes())) {
			if (attribute.hasAnyAnnotation()) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Return the AccessType currently implied by the Java source code:
	 *     - if only Fields are annotated => FIELD
	 *     - if only Properties are annotated => PROPERTY
	 *     - if both Fields and Properties are annotated => FIELD
	 *     - if nothing is annotated
	 *     		- and fields exist => FIELD
	 *     		- and properties exist, but no fields exist => PROPERTY
	 *     		- and neither fields nor properties exist => null at this level (FIELD in the context model)
	 */
	private AccessType calculateAccessType() {
		boolean hasPersistableFields = false;
		boolean hasPersistableProperties = false;
		for (JavaPersistentAttributeResource field : CollectionTools.iterable(fields())) {
			hasPersistableFields = true;
			if (field.hasAnyAnnotation()) {
				// any field is annotated => FIELD
				return AccessType.FIELD;
			}
		}
		for (JavaPersistentAttributeResource property : CollectionTools.iterable(properties())) {
			hasPersistableProperties = true;
			if (property.hasAnyAnnotation()) {
				// none of the fields are annotated and a getter is annotated => PROPERTY
				return AccessType.PROPERTY;
			}
		}

		if (hasPersistableProperties && !hasPersistableFields) {
			return AccessType.PROPERTY;
		}
		//no annotations exist, access is null at the resource model level
		return null;
	}
	
	private String superClassQualifiedName(CompilationUnit astRoot) {
		ITypeBinding typeBinding = getMember().binding(astRoot);
		if (typeBinding == null) {
			return null;
		}
		ITypeBinding superClassTypeBinding = typeBinding.getSuperclass();
		if (superClassTypeBinding == null) {
			return null;
		}
		return superClassTypeBinding.getQualifiedName();
	}
	
	@Override
	public void toString(StringBuilder sb) {
		sb.append(getName());
	}

}
