/*******************************************************************************
 * 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.List;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.core.internal.utility.jdt.ConversionDeclarationAnnotationElementAdapter;
import org.eclipse.jpt.core.internal.utility.jdt.EnumArrayDeclarationAnnotationElementAdapter;
import org.eclipse.jpt.core.internal.utility.jdt.EnumDeclarationAnnotationElementAdapter;
import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
import org.eclipse.jpt.core.internal.utility.jdt.ShortCircuitAnnotationElementAdapter;
import org.eclipse.jpt.core.internal.utility.jdt.ShortCircuitArrayAnnotationElementAdapter;
import org.eclipse.jpt.core.internal.utility.jdt.SimpleTypeStringExpressionConverter;
import org.eclipse.jpt.core.resource.java.CascadeType;
import org.eclipse.jpt.core.resource.java.FetchType;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
import org.eclipse.jpt.core.resource.java.RelationshipMappingAnnotation;
import org.eclipse.jpt.core.utility.TextRange;
import org.eclipse.jpt.core.utility.jdt.AnnotationElementAdapter;
import org.eclipse.jpt.core.utility.jdt.Attribute;
import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationAdapter;
import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationElementAdapter;
import org.eclipse.jpt.core.utility.jdt.ExpressionConverter;
import org.eclipse.jpt.utility.internal.CollectionTools;


public abstract class AbstractRelationshipMappingAnnotation extends AbstractResourceAnnotation<Attribute> implements RelationshipMappingAnnotation
{
	// hold this so we can get the 'targetEntity' text range
	private final DeclarationAnnotationElementAdapter<String> targetEntityDeclarationAdapter;
	
	// hold this so we can get the 'fetch' text range
	private final DeclarationAnnotationElementAdapter<String> fetchDeclarationAdapter;
	
	// hold this so we can get the 'cascade' text range
	private final DeclarationAnnotationElementAdapter<String[]> cascadeDeclarationAdapter;
	
	private final AnnotationElementAdapter<String> targetEntityAdapter;

	private final AnnotationElementAdapter<String> fetchAdapter;

	private final AnnotationElementAdapter<String[]> cascadeAdapter;

	private String targetEntity;

	private String fullyQualifiedTargetEntity;

	private FetchType fetch;
	
	protected boolean cascadeAll;

	protected boolean cascadePersist;

	protected boolean cascadeMerge;

	protected boolean cascadeRemove;

	protected boolean cascadeRefresh;

	
	public AbstractRelationshipMappingAnnotation(JavaResourcePersistentAttribute parent, Attribute attribute, DeclarationAnnotationAdapter daa) {
		super(parent, attribute, daa);
		this.targetEntityDeclarationAdapter = targetEntityAdapter();
		this.targetEntityAdapter = buildAnnotationElementAdapter(this.targetEntityDeclarationAdapter);
		this.fetchDeclarationAdapter = fetchAdapter();
		this.fetchAdapter = buildAnnotationElementAdapter(this.fetchDeclarationAdapter);
		this.cascadeDeclarationAdapter = cascadeAdapter();
		this.cascadeAdapter = new ShortCircuitArrayAnnotationElementAdapter<String>(attribute, this.cascadeDeclarationAdapter);
	}
	
	protected AnnotationElementAdapter<String> buildAnnotationElementAdapter(DeclarationAnnotationElementAdapter<String> daea) {
		return new ShortCircuitAnnotationElementAdapter<String>(this.getMember(), daea);
	}
	
	protected AnnotationElementAdapter<Boolean> buildBooleanAnnotationElementAdapter(DeclarationAnnotationElementAdapter<Boolean> daea) {
		return new ShortCircuitAnnotationElementAdapter<Boolean>(this.getMember(), daea);
	}

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

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

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

	public void initialize(CompilationUnit astRoot) {
		this.targetEntity = this.targetEntity(astRoot);
		this.fullyQualifiedTargetEntity = this.fullyQualifiedTargetEntity(astRoot);
		this.fetch = this.fetch(astRoot);
		this.initializeCascadeTypes(astRoot);
	}
	
	protected void initializeCascadeTypes(CompilationUnit astRoot) {
		String[] javaValue = this.cascadeAdapter.getValue(astRoot);
		CascadeType[] cascadeTypes = CascadeType.fromJavaAnnotationValue(javaValue);
		
		this.cascadeAll = CollectionTools.contains(cascadeTypes, CascadeType.ALL);
		this.cascadeMerge = CollectionTools.contains(cascadeTypes, CascadeType.MERGE);
		this.cascadePersist = CollectionTools.contains(cascadeTypes, CascadeType.PERSIST);
		this.cascadeRefresh = CollectionTools.contains(cascadeTypes, CascadeType.REFRESH);
		this.cascadeRemove = CollectionTools.contains(cascadeTypes, CascadeType.REMOVE);
	}
	
	public String getTargetEntity() {
		return this.targetEntity;
	}
	
	public void setTargetEntity(String newTargetEntity) {
		if (attributeValueHasNotChanged(this.targetEntity, newTargetEntity)) {
			return;
		}
		String oldTargetEntity = this.targetEntity;
		this.targetEntity = newTargetEntity;
		this.targetEntityAdapter.setValue(newTargetEntity);
		firePropertyChanged(TARGET_ENTITY_PROPERTY, oldTargetEntity, newTargetEntity);
	}
	
	public String getFullyQualifiedTargetEntity() {
		return this.fullyQualifiedTargetEntity;
	}
	
	protected void setFullyQualifiedTargetEntity(String newTargetEntity) {
		String oldTargetEntity = this.fullyQualifiedTargetEntity;
		this.fullyQualifiedTargetEntity = newTargetEntity;
		firePropertyChanged(FULLY_QUALFIEID_TARGET_ENTITY_PROPERTY, oldTargetEntity, newTargetEntity);
	}
	
	public FetchType getFetch() {
		return this.fetch;
	}
	
	public void setFetch(FetchType newFetch) {
		if (attributeValueHasNotChanged(this.fetch, newFetch)) {
			return;
		}
		FetchType oldFetch = this.fetch;
		this.fetch = newFetch;
		this.fetchAdapter.setValue(FetchType.toJavaAnnotationValue(newFetch));
		firePropertyChanged(FETCH_PROPERTY, oldFetch, newFetch);
	}
		
	public boolean isCascadeAll() {
		return this.cascadeAll;
	}
	
	public void setCascadeAll(boolean newCascadeAll) {
		if (this.cascadeAll == newCascadeAll) {
			return;
		}
		boolean oldCascadeAll = this.cascadeAll;
		this.cascadeAll = newCascadeAll;
		setCascade(newCascadeAll, CascadeType.ALL);
		firePropertyChanged(CASCADE_ALL_PROPERTY, oldCascadeAll, newCascadeAll);
	}
	
	public boolean isCascadePersist() {
		return this.cascadePersist;
	}
	
	public void setCascadePersist(boolean newCascadePersist) {
		if (this.cascadePersist == newCascadePersist) {
			return;
		}
		boolean oldCascadePersist = this.cascadePersist;
		this.cascadePersist = newCascadePersist;
		setCascade(newCascadePersist, CascadeType.PERSIST);
		firePropertyChanged(CASCADE_PERSIST_PROPERTY, oldCascadePersist, newCascadePersist);
	}
	
	public boolean isCascadeMerge() {
		return this.cascadeMerge;
	}
	
	public void setCascadeMerge(boolean newCascadeMerge) {
		if (this.cascadeMerge == newCascadeMerge) {
			return;
		}
		boolean oldCascadeMerge = this.cascadeMerge;
		this.cascadeMerge = newCascadeMerge;
		setCascade(newCascadeMerge, CascadeType.MERGE);
		firePropertyChanged(CASCADE_MERGE_PROPERTY, oldCascadeMerge, newCascadeMerge);
	}
	
	public boolean isCascadeRemove() {
		return this.cascadeRemove;
	}
	
	public void setCascadeRemove(boolean newCascadeRemove) {
		if (this.cascadeRemove == newCascadeRemove) {
			return;
		}
		boolean oldCascadeRemove = this.cascadeRemove;
		this.cascadeRemove = newCascadeRemove;
		setCascade(newCascadeRemove, CascadeType.REMOVE);
		firePropertyChanged(CASCADE_REMOVE_PROPERTY, oldCascadeRemove, newCascadeRemove);
	}
	
	public boolean isCascadeRefresh() {
		return this.cascadeRefresh;
	}
	
	public void setCascadeRefresh(boolean newCascadeRefresh) {
		if (this.cascadeRefresh == newCascadeRefresh) {
			return;
		}
		boolean oldCascadeRefresh = this.cascadeRefresh;
		this.cascadeRefresh = newCascadeRefresh;
		setCascade(newCascadeRefresh, CascadeType.REFRESH);
		firePropertyChanged(CASCADE_REFRESH_PROPERTY, oldCascadeRefresh, newCascadeRefresh);
	}
	
	private void setCascadeTypes(CascadeType[] cascadeTypes) {
		String[] newJavaValue = CascadeType.toJavaAnnotationValue(cascadeTypes);
		this.cascadeAdapter.setValue(newJavaValue);
	}
	
	private void setCascade(boolean isSet, CascadeType cascadeType) {
		String[] javaValue = this.cascadeAdapter.getValue();
		CascadeType[] cascadeTypes = CascadeType.fromJavaAnnotationValue(javaValue);	
		List<CascadeType> cascadeCollection = CollectionTools.list(cascadeTypes);

		if (cascadeCollection.contains(cascadeType)) {
			if (!isSet) {
				cascadeCollection.remove(cascadeType);
				setCascadeTypes(cascadeCollection.toArray(new CascadeType[cascadeCollection.size()]));
			}
		}
		else {
			if (isSet) {
				cascadeCollection.add(cascadeType);
				setCascadeTypes(cascadeCollection.toArray(new CascadeType[cascadeCollection.size()]));
			}
		}
	}
	
	public TextRange getTargetEntityTextRange(CompilationUnit astRoot) {
		return getElementTextRange(this.targetEntityDeclarationAdapter, astRoot);
	}
	
	public TextRange getFetchTextRange(CompilationUnit astRoot) {
		return getElementTextRange(this.fetchDeclarationAdapter, astRoot);
	}
	
	public TextRange getCascadeTextRange(CompilationUnit astRoot) {
		return getElementTextRange(this.cascadeDeclarationAdapter, astRoot);
	}
	
	public void updateFromJava(CompilationUnit astRoot) {
		this.setFetch(this.fetch(astRoot));
		this.setTargetEntity(this.targetEntity(astRoot));
		this.setFullyQualifiedTargetEntity(this.fullyQualifiedTargetEntity(astRoot));
		this.updateCascadeFromJava(astRoot);
	}
	
	protected FetchType fetch(CompilationUnit astRoot) {
		return FetchType.fromJavaAnnotationValue(this.fetchAdapter.getValue(astRoot));
	}
	
	protected String targetEntity(CompilationUnit astRoot) {
		return this.targetEntityAdapter.getValue(astRoot);
	}
	
	private void updateCascadeFromJava(CompilationUnit astRoot) {
		String[] javaValue = this.cascadeAdapter.getValue(astRoot);
		CascadeType[] cascadeTypes = CascadeType.fromJavaAnnotationValue(javaValue);
		setCascadeAll(CollectionTools.contains(cascadeTypes, CascadeType.ALL));
		setCascadeMerge(CollectionTools.contains(cascadeTypes, CascadeType.MERGE));
		setCascadePersist(CollectionTools.contains(cascadeTypes, CascadeType.PERSIST));
		setCascadeRefresh(CollectionTools.contains(cascadeTypes, CascadeType.REFRESH));
		setCascadeRemove(CollectionTools.contains(cascadeTypes, CascadeType.REMOVE));
	}
	
	private String fullyQualifiedTargetEntity(CompilationUnit astRoot) {
		if (getTargetEntity() == null) {
			return null;
		}
		return JDTTools.resolveFullyQualifiedName(this.targetEntityAdapter.getExpression(astRoot));
	}

	// ********** static methods **********
	
	protected static DeclarationAnnotationElementAdapter<String> buildTargetEntityAdapter(DeclarationAnnotationAdapter annotationAdapter, String elementName) {
		// TODO what about QualifiedType?
		return buildAnnotationElementAdapter(annotationAdapter, elementName, SimpleTypeStringExpressionConverter.instance());
	}
	
	protected static DeclarationAnnotationElementAdapter<String> buildAnnotationElementAdapter(DeclarationAnnotationAdapter annotationAdapter, String elementName, ExpressionConverter<String> converter) {
		return new ConversionDeclarationAnnotationElementAdapter<String>(annotationAdapter, elementName, false, converter);
	}
	
	protected static DeclarationAnnotationElementAdapter<String> buildFetchAdapter(DeclarationAnnotationAdapter annotationAdapter, String elementName) {
		return new EnumDeclarationAnnotationElementAdapter(annotationAdapter, elementName, false);
	}
	
	protected static DeclarationAnnotationElementAdapter<String[]> buildEnumArrayAnnotationElementAdapter(DeclarationAnnotationAdapter annotationAdapter, String elementName) {
		return new EnumArrayDeclarationAnnotationElementAdapter(annotationAdapter, elementName, false);
	}

}
