/*******************************************************************************
 * Copyright (c) 2009 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.binary;

import java.util.Iterator;
import java.util.ListIterator;
import java.util.Vector;

import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.core.JptCorePlugin;
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.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.iterables.CloneIterable;
import org.eclipse.jpt.utility.internal.iterables.FixedCloneIterable;
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;

/**
 * binary persistent member
 */
abstract class BinaryPersistentMember
	extends BinaryNode
	implements JavaResourcePersistentMember
{
	/** JDT member adapter */
	final Adapter adapter;

	/** mapping annotations */
	final Vector<Annotation> mappingAnnotations = new Vector<Annotation>();

	/** supporting annotations */
	final Vector<Annotation> supportingAnnotations = new Vector<Annotation>();

	boolean persistable;


	// ********** construction/initialization **********

	public BinaryPersistentMember(JavaResourceNode parent, Adapter adapter) {
		super(parent);
		this.adapter = adapter;
		this.initializeAnnotations();
		this.persistable = this.buildPersistable();
	}

	private void initializeAnnotations() {
		for (IAnnotation annotation : this.getJdtAnnotations()) {
			this.addAnnotation(annotation);
		}
	}

	private void addAnnotation(IAnnotation jdtAnnotation) {
		if (this.annotationIsValidSupportingAnnotation(jdtAnnotation)) {
			this.supportingAnnotations.add(this.buildSupportingAnnotation(jdtAnnotation));
		} else if (this.annotationIsValidMappingAnnotation(jdtAnnotation)) {
			this.mappingAnnotations.add(this.buildMappingAnnotation(jdtAnnotation));
		}
	}


	// ********** updating **********

	@Override
	public void update() {
		super.update();
		this.updateAnnotations();
		this.setPersistable(this.buildPersistable());
	}

	// TODO
	private void updateAnnotations() {
		throw new UnsupportedOperationException();
	}


	// ********** mapping annotations **********

	public Iterator<Annotation> mappingAnnotations() {
		return new CloneIterator<Annotation>(this.mappingAnnotations);
	}

	private Iterable<Annotation> getMappingAnnotations() {
		return new CloneIterable<Annotation>(this.mappingAnnotations);
	}

	public int mappingAnnotationsSize() {
		return this.mappingAnnotations.size();
	}

	public Annotation getMappingAnnotation() {
		Iterable<Annotation> annotations = new FixedCloneIterable<Annotation>(this.mappingAnnotations);
		for (ListIterator<String> stream = this.validMappingAnnotationNames(); stream.hasNext();) {
			Annotation annotation = this.getAnnotation(annotations, stream.next());
			if (annotation != null) {
				return annotation;
			}
		}
		return null;
	}

	public Annotation getMappingAnnotation(String annotationName) {
		return this.getAnnotation(this.getMappingAnnotations(), annotationName);
	}

	private boolean annotationIsValidMappingAnnotation(IAnnotation jdtAnnotation) {
		return CollectionTools.contains(this.validMappingAnnotationNames(), jdtAnnotation.getElementName());
	}

	abstract ListIterator<String> validMappingAnnotationNames();

	abstract Annotation buildMappingAnnotation(IAnnotation jdtAnnotation);


	// ********** supporting annotations **********

	public Iterator<Annotation> supportingAnnotations() {
		return new CloneIterator<Annotation>(this.supportingAnnotations);
	}

	private Iterable<Annotation> getSupportingAnnotations() {
		return new CloneIterable<Annotation>(this.supportingAnnotations);
	}

	public int supportingAnnotationsSize() {
		return this.supportingAnnotations.size();
	}

	public ListIterator<NestableAnnotation> supportingAnnotations(String nestableAnnotationName, String containerAnnotationName) {
		ContainerAnnotation<NestableAnnotation> containerAnnotation = this.getSupportingContainerAnnotation(containerAnnotationName);
		if (containerAnnotation != null) {
			return containerAnnotation.nestedAnnotations();
		}
		NestableAnnotation nestableAnnotation = this.getSupportingNestableAnnotation(nestableAnnotationName);
		return (nestableAnnotation == null) ? EmptyListIterator.<NestableAnnotation>instance() : new SingleElementListIterator<NestableAnnotation>(nestableAnnotation);
	}

	private NestableAnnotation getSupportingNestableAnnotation(String annotationName) {
		return (NestableAnnotation) this.getSupportingAnnotation(annotationName);
	}

	public Annotation getSupportingAnnotation(String annotationName) {
		return this.getAnnotation(this.getSupportingAnnotations(), annotationName);
	}

	public Annotation getNonNullSupportingAnnotation(String annotationName) {
		Annotation annotation = this.getSupportingAnnotation(annotationName);
		return (annotation != null) ? annotation : this.buildNullSupportingAnnotation(annotationName);
	}

	abstract Annotation buildNullSupportingAnnotation(String annotationName);

	abstract Annotation buildSupportingAnnotation(IAnnotation jdtAnnotation);

	private boolean annotationIsValidSupportingAnnotation(IAnnotation jdtAnnotation) {
		return CollectionTools.contains(this.validSupportingAnnotationNames(), jdtAnnotation.getElementName());
	}

	abstract ListIterator<String> validSupportingAnnotationNames();

	@SuppressWarnings("unchecked")
	private ContainerAnnotation<NestableAnnotation> getSupportingContainerAnnotation(String annotationName) {
		return (ContainerAnnotation<NestableAnnotation>) this.getSupportingAnnotation(annotationName);
	}


	// ********** simple state **********

	public boolean isPersistable() {
		return this.persistable;
	}

	private void setPersistable(boolean persistable) {
		boolean old = this.persistable;
		this.persistable = persistable;
		this.firePropertyChanged(PERSISTABLE_PROPERTY, old, persistable);
	}

	private boolean buildPersistable() {
		return this.adapter.isPersistable();
	}

	public boolean isPersisted() {
		return this.getMappingAnnotation() != null;
	}


	// ********** miscellaneous **********

	public IMember getMember() {
		return this.adapter.getMember();
	}

	private Annotation getAnnotation(Iterable<Annotation> annotations, String annotationName) {
		for (Annotation annotation : annotations) {
			if (annotation.getAnnotationName().equals(annotationName)) {
				return annotation;
			}
		}
		return null;
	}

	/**
	 * convenience method
	 */
	<T extends JavaResourcePersistentMember> Iterator<T> persistableMembers(Iterator<T> members) {
		return new FilteringIterator<T, T>(members) {
			@Override
			protected boolean accept(T m) {
				return m.isPersistable();
			}
		};
	}

	private IAnnotation[] getJdtAnnotations() {
		try {
			return this.adapter.getAnnotations();
		} catch (JavaModelException ex) {
			JptCorePlugin.log(ex);
			return EMPTY_JDT_ANNOTATION_ARRAY;
		}
	}
	private static final IAnnotation[] EMPTY_JDT_ANNOTATION_ARRAY = new IAnnotation[0];


	// ********** IMember adapter **********

	interface Adapter {
		IMember getMember();
		boolean isPersistable();
		IAnnotation[] getAnnotations() throws JavaModelException;
	}


	// ********** unsupported JavaResourcePersistentMember implementation **********

	public Annotation setMappingAnnotation(String annotationName) {
		throw new UnsupportedOperationException();
	}

	public Annotation addSupportingAnnotation(String annotationName) {
		throw new UnsupportedOperationException();
	}

	public Annotation addSupportingAnnotation(int index, String nestableAnnotationName, String containerAnnotationName) {
		throw new UnsupportedOperationException();
	}

	public void moveSupportingAnnotation(int targetIndex, int sourceIndex, String containerAnnotationName) {
		throw new UnsupportedOperationException();
	}

	public void removeSupportingAnnotation(String annotationName) {
		throw new UnsupportedOperationException();
	}

	public void removeSupportingAnnotation(int index, String nestableAnnotationName, String containerAnnotationName) {
		throw new UnsupportedOperationException();
	}

	public TextRange getNameTextRange(CompilationUnit astRoot) {
		throw new UnsupportedOperationException();
	}

	public void resolveTypes(CompilationUnit astRoot) {
		throw new UnsupportedOperationException();
	}

	public boolean isFor(String memberName, int occurrence) {
		throw new UnsupportedOperationException();
	}

}
