/*******************************************************************************
 * Copyright (c) 2007, 2011 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.jpa.core.internal.resource.java.source;

import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.internal.resource.java.source.SourceAnnotation;
import org.eclipse.jpt.common.core.internal.utility.jdt.ASTTools;
import org.eclipse.jpt.common.core.internal.utility.jdt.AnnotatedElementAnnotationElementAdapter;
import org.eclipse.jpt.common.core.internal.utility.jdt.ConversionDeclarationAnnotationElementAdapter;
import org.eclipse.jpt.common.core.internal.utility.jdt.EnumArrayDeclarationAnnotationElementAdapter;
import org.eclipse.jpt.common.core.internal.utility.jdt.EnumDeclarationAnnotationElementAdapter;
import org.eclipse.jpt.common.core.internal.utility.jdt.SimpleTypeStringExpressionConverter;
import org.eclipse.jpt.common.core.resource.java.JavaResourceAnnotatedElement;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.core.utility.jdt.AnnotatedElement;
import org.eclipse.jpt.common.core.utility.jdt.AnnotationElementAdapter;
import org.eclipse.jpt.common.core.utility.jdt.DeclarationAnnotationAdapter;
import org.eclipse.jpt.common.core.utility.jdt.DeclarationAnnotationElementAdapter;
import org.eclipse.jpt.common.core.utility.jdt.ExpressionConverter;
import org.eclipse.jpt.common.utility.internal.ArrayTools;
import org.eclipse.jpt.jpa.core.jpa2.resource.java.RelationshipMapping2_0Annotation;
import org.eclipse.jpt.jpa.core.resource.java.CascadeType;
import org.eclipse.jpt.jpa.core.resource.java.FetchType;

/**
 * javax.persistence.ManyToMany
 * javax.persistence.ManyToOne
 * javax.persistence.OneToMany
 * javax.persistence.OneToOne
 */
abstract class SourceRelationshipMappingAnnotation
	extends SourceAnnotation
	implements RelationshipMapping2_0Annotation
{
	final DeclarationAnnotationElementAdapter<String> targetEntityDeclarationAdapter;
	final AnnotationElementAdapter<String> targetEntityAdapter;
	String targetEntity;

	/**
	 * @see org.eclipse.jpt.jpa.core.internal.resource.java.source.SourceIdClassAnnotation#fullyQualifiedClassName
	 */
	private String fullyQualifiedTargetEntityClassName;
	// we need a flag since the f-q name can be null
	private boolean fqTargetEntityClassNameStale = true;

	final DeclarationAnnotationElementAdapter<String> fetchDeclarationAdapter;
	final AnnotationElementAdapter<String> fetchAdapter;
	FetchType fetch;

	final DeclarationAnnotationElementAdapter<String[]> cascadeDeclarationAdapter;
	final AnnotationElementAdapter<String[]> cascadeAdapter;
	CascadeType[] cascadeTypes = EMPTY_CASCADE_TYPE_ARRAY;  // this should never be null
	private static final CascadeType[] EMPTY_CASCADE_TYPE_ARRAY = new CascadeType[0];


	SourceRelationshipMappingAnnotation(JavaResourceAnnotatedElement parent, AnnotatedElement element, DeclarationAnnotationAdapter daa) {
		super(parent, element, daa);
		this.targetEntityDeclarationAdapter = this.getTargetEntityAdapter();
		this.targetEntityAdapter = this.buildAnnotationElementAdapter(this.targetEntityDeclarationAdapter);
		this.fetchDeclarationAdapter = this.getFetchAdapter();
		this.fetchAdapter = this.buildAnnotationElementAdapter(this.fetchDeclarationAdapter);
		this.cascadeDeclarationAdapter = this.getCascadeAdapter();
		this.cascadeAdapter = new AnnotatedElementAnnotationElementAdapter<String[]>(element, this.cascadeDeclarationAdapter);
	}

	protected AnnotationElementAdapter<String> buildAnnotationElementAdapter(DeclarationAnnotationElementAdapter<String> daea) {
		return new AnnotatedElementAnnotationElementAdapter<String>(this.annotatedElement, daea);
	}

	protected AnnotationElementAdapter<Boolean> buildBooleanAnnotationElementAdapter(DeclarationAnnotationElementAdapter<Boolean> daea) {
		return new AnnotatedElementAnnotationElementAdapter<Boolean>(this.annotatedElement, daea);
	}

	public void initialize(CompilationUnit astRoot) {
		this.targetEntity = this.buildTargetEntity(astRoot);
		this.fetch = this.buildFetch(astRoot);
		this.cascadeTypes = this.buildCascadeTypes(astRoot);
	}

	public void synchronizeWith(CompilationUnit astRoot) {
		this.syncFetch(this.buildFetch(astRoot));
		this.syncTargetEntity(this.buildTargetEntity(astRoot));
		this.syncCascadeTypes(this.buildCascadeTypes(astRoot));
	}

	@Override
	public boolean isUnset() {
		return super.isUnset() &&
				(this.targetEntity == null) &&
				(this.fetch == null) &&
				(this.cascadeTypes.length == 0);
	}

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


	// ********** RelationshipMappingAnnotation implementation **********

	// ***** target entity
	public String getTargetEntity() {
		return this.targetEntity;
	}

	public void setTargetEntity(String targetEntity) {
		if (this.attributeValueHasChanged(this.targetEntity, targetEntity)) {
			this.targetEntity = targetEntity;
			this.fqTargetEntityClassNameStale = true;
			this.targetEntityAdapter.setValue(targetEntity);
		}
	}

	private void syncTargetEntity(String astTargetEntity) {
		if (this.attributeValueHasChanged(this.targetEntity, astTargetEntity)) {
			this.syncTargetEntity_(astTargetEntity);
		}
	}

	private void syncTargetEntity_(String astTargetEntity) {
		String old = this.targetEntity;
		this.targetEntity = astTargetEntity;
		this.fqTargetEntityClassNameStale = true;
		this.firePropertyChanged(TARGET_ENTITY_PROPERTY, old, astTargetEntity);
	}

	private String buildTargetEntity(CompilationUnit astRoot) {
		return this.targetEntityAdapter.getValue(astRoot);
	}

	public TextRange getTargetEntityTextRange(CompilationUnit astRoot) {
		return this.getElementTextRange(this.targetEntityDeclarationAdapter, astRoot);
	}

	/**
	 * return the Java adapter's 'targetEntity' element adapter config
	 */
	abstract DeclarationAnnotationElementAdapter<String> getTargetEntityAdapter();

	// ***** fully-qualified target entity class name
	public String getFullyQualifiedTargetEntityClassName() {
		if (this.fqTargetEntityClassNameStale) {
			this.fullyQualifiedTargetEntityClassName = this.buildFullyQualifiedTargetEntityClassName();
			this.fqTargetEntityClassNameStale = false;
		}
		return this.fullyQualifiedTargetEntityClassName;
	}

	private String buildFullyQualifiedTargetEntityClassName() {
		return (this.targetEntity == null) ? null : this.buildFullyQualifiedTargetEntityClassName_();
	}

	private String buildFullyQualifiedTargetEntityClassName_() {
		return ASTTools.resolveFullyQualifiedName(this.targetEntityAdapter.getExpression(this.buildASTRoot()));
	}

	// ***** fetch
	public FetchType getFetch() {
		return this.fetch;
	}

	public void setFetch(FetchType fetch) {
		if (this.attributeValueHasChanged(this.fetch, fetch)) {
			this.fetch = fetch;
			this.fetchAdapter.setValue(FetchType.toJavaAnnotationValue(fetch));
		}
	}

	private void syncFetch(FetchType astFetch) {
		FetchType old = this.fetch;
		this.fetch = astFetch;
		this.firePropertyChanged(FETCH_PROPERTY, old, astFetch);
	}

	private FetchType buildFetch(CompilationUnit astRoot) {
		return FetchType.fromJavaAnnotationValue(this.fetchAdapter.getValue(astRoot));
	}

	public TextRange getFetchTextRange(CompilationUnit astRoot) {
		return this.getElementTextRange(this.fetchDeclarationAdapter, astRoot);
	}

	/**
	 * return the Java adapter's 'fetch' element adapter config
	 */
	abstract DeclarationAnnotationElementAdapter<String> getFetchAdapter();

	// ***** cascade types
	/**
	 * pre-condition: state of 'cascadeTypes' is to change
	 */
	private void setCascadeType(CascadeType cascadeType, boolean set) {
		this.setCascadeTypes(set ?
			ArrayTools.add(this.cascadeTypes, cascadeType) :
			ArrayTools.remove(this.cascadeTypes, cascadeType)
		);
	}

	/**
	 * pre-condition: state of 'cascadeTypes' is to change
	 */
	private void setCascadeTypes(CascadeType[] cascadeTypes) {
		this.cascadeTypes = cascadeTypes;
		this.cascadeAdapter.setValue(CascadeType.toJavaAnnotationValues(cascadeTypes));
	}

	private void syncCascadeTypes(CascadeType[] astCascadeTypes) {
		CascadeType[] old = this.cascadeTypes;
		this.cascadeTypes = astCascadeTypes;
		this.syncCascadeAll(old);
		this.syncCascadeMerge(old);
		this.syncCascadePersist(old);
		this.syncCascadeRefresh(old);
		this.syncCascadeRemove(old);
		this.syncCascadeDetach(old);
	}

	private CascadeType[] buildCascadeTypes(CompilationUnit astRoot) {
		return CascadeType.fromJavaAnnotationValues(this.cascadeAdapter.getValue(astRoot));
	}

	private boolean cascadeTypeIsTrue(CascadeType cascadeType) {
		return ArrayTools.contains(this.cascadeTypes, cascadeType);
	}

	public TextRange getCascadeTextRange(CompilationUnit astRoot) {
		return getElementTextRange(this.cascadeDeclarationAdapter, astRoot);
	}

	/**
	 * return the Java adapter's 'cascade' element adapter config
	 */
	abstract DeclarationAnnotationElementAdapter<String[]> getCascadeAdapter();

	// ***** cascade all
	public boolean isCascadeAll() {
		return this.cascadeTypeIsTrue(CascadeType.ALL);
	}

	public void setCascadeAll(boolean cascadeAll) {
		if (this.isCascadeAll() != cascadeAll) {
			this.setCascadeType(CascadeType.ALL, cascadeAll);
		}
	}

	private void syncCascadeAll(CascadeType[] oldCascadeTypes) {
		boolean old = ArrayTools.contains(oldCascadeTypes, CascadeType.ALL);
		this.firePropertyChanged(CASCADE_ALL_PROPERTY, old, this.isCascadeAll());
	}

	// ***** cascade persist
	public boolean isCascadePersist() {
		return this.cascadeTypeIsTrue(CascadeType.PERSIST);
	}

	public void setCascadePersist(boolean cascadePersist) {
		if (this.isCascadePersist() != cascadePersist) {
			this.setCascadeType(CascadeType.PERSIST, cascadePersist);
		}
	}

	private void syncCascadePersist(CascadeType[] oldCascadeTypes) {
		boolean old = ArrayTools.contains(oldCascadeTypes, CascadeType.PERSIST);
		this.firePropertyChanged(CASCADE_PERSIST_PROPERTY, old, this.isCascadePersist());
	}

	// ***** cascade merge
	public boolean isCascadeMerge() {
		return this.cascadeTypeIsTrue(CascadeType.MERGE);
	}

	public void setCascadeMerge(boolean cascadeMerge) {
		if (this.isCascadeMerge() != cascadeMerge) {
			this.setCascadeType(CascadeType.MERGE, cascadeMerge);
		}
	}

	private void syncCascadeMerge(CascadeType[] oldCascadeTypes) {
		boolean old = ArrayTools.contains(oldCascadeTypes, CascadeType.MERGE);
		this.firePropertyChanged(CASCADE_MERGE_PROPERTY, old, this.isCascadeMerge());
	}

	// ***** cascade remove
	public boolean isCascadeRemove() {
		return this.cascadeTypeIsTrue(CascadeType.REMOVE);
	}

	public void setCascadeRemove(boolean cascadeRemove) {
		if (this.isCascadeRemove() != cascadeRemove) {
			this.setCascadeType(CascadeType.REMOVE, cascadeRemove);
		}
	}

	private void syncCascadeRemove(CascadeType[] oldCascadeTypes) {
		boolean old = ArrayTools.contains(oldCascadeTypes, CascadeType.REMOVE);
		this.firePropertyChanged(CASCADE_REMOVE_PROPERTY, old, this.isCascadeRemove());
	}

	// ***** cascade refresh
	public boolean isCascadeRefresh() {
		return this.cascadeTypeIsTrue(CascadeType.REFRESH);
	}

	public void setCascadeRefresh(boolean cascadeRefresh) {
		if (this.isCascadeRefresh() != cascadeRefresh) {
			this.setCascadeType(CascadeType.REFRESH, cascadeRefresh);
		}
	}

	private void syncCascadeRefresh(CascadeType[] oldCascadeTypes) {
		boolean old = ArrayTools.contains(oldCascadeTypes, CascadeType.REFRESH);
		this.firePropertyChanged(CASCADE_REFRESH_PROPERTY, old, this.isCascadeRefresh());
	}

	// ***** cascade detach - JPA 2.0
	public boolean isCascadeDetach() {
		return this.cascadeTypeIsTrue(CascadeType.DETACH);
	}

	public void setCascadeDetach(boolean cascadeDetach) {
		if (this.isCascadeDetach() != cascadeDetach) {
			this.setCascadeType(CascadeType.DETACH, cascadeDetach);
		}
	}

	private void syncCascadeDetach(CascadeType[] oldCascadeTypes) {
		boolean old = ArrayTools.contains(oldCascadeTypes, CascadeType.DETACH);
		this.firePropertyChanged(CASCADE_DETACH_PROPERTY, old, this.isCascadeDetach());
	}

	// ********** static methods **********

	static DeclarationAnnotationElementAdapter<String> buildTargetEntityAdapter(DeclarationAnnotationAdapter annotationAdapter, String elementName) {
		// TODO what about QualifiedType?
		return buildAnnotationElementAdapter(annotationAdapter, elementName, SimpleTypeStringExpressionConverter.instance());
	}

	static DeclarationAnnotationElementAdapter<String> buildAnnotationElementAdapter(DeclarationAnnotationAdapter annotationAdapter, String elementName, ExpressionConverter<String> converter) {
		return new ConversionDeclarationAnnotationElementAdapter<String>(annotationAdapter, elementName, converter);
	}

	static DeclarationAnnotationElementAdapter<String> buildFetchAdapter(DeclarationAnnotationAdapter annotationAdapter, String elementName) {
		return new EnumDeclarationAnnotationElementAdapter(annotationAdapter, elementName);
	}

	static DeclarationAnnotationElementAdapter<String[]> buildEnumArrayAnnotationElementAdapter(DeclarationAnnotationAdapter annotationAdapter, String elementName) {
		return new EnumArrayDeclarationAnnotationElementAdapter(annotationAdapter, elementName);
	}

}
