/*******************************************************************************
 * Copyright (c) 2005, 2007 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.jdtutility;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jpt.core.internal.ITextRange;
import org.eclipse.jpt.core.internal.SimpleTextRange;
import org.eclipse.jpt.utility.internal.Command;
import org.eclipse.jpt.utility.internal.CommandExecutor;
import org.eclipse.jpt.utility.internal.CommandExecutorProvider;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.TextEdit;

/**
 * Adapt and extend a JDT member with simplified annotation handling.
 */
public abstract class Member {

	private final IMember jdtMember;

	/** this will be null for a top-level type */
	private final Type declaringType;

	private final CommandExecutorProvider modifySharedDocumentCommandExecutorProvider;


	// ********** constructor **********

	Member(IMember jdtMember, CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
		super();
		this.jdtMember = jdtMember;
		IType jdtDeclaringType = jdtMember.getDeclaringType();
		this.declaringType = (jdtDeclaringType == null) ? null : new Type(jdtDeclaringType, modifySharedDocumentCommandExecutorProvider);
		this.modifySharedDocumentCommandExecutorProvider = modifySharedDocumentCommandExecutorProvider;
	}


	// ********** accessors **********

	public IMember getJdtMember() {
		return this.jdtMember;
	}

	public boolean wraps(IMember member) {
		return this.jdtMember.exists()
				&& this.jdtMember.equals(member);
	}

	/**
	 * this will return null for a top-level type
	 */
	public Type getDeclaringType() {
		return this.declaringType;
	}


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

	public ICompilationUnit compilationUnit() {
		return this.jdtMember.getCompilationUnit();
	}

	public String getName() {
		return this.jdtMember.getElementName();
	}

	public Type topLevelDeclaringType() {
		return this.declaringType.topLevelDeclaringType();
	}

	/**
	 * note: this creates a *new* AST
	 */
	public CompilationUnit astRoot() {
		return JDTTools.buildASTRoot(this.jdtMember);
	}

	/**
	 * note: this creates a *new* AST
	 */
	private CompilationUnit lightweightASTRoot() {
		return JDTTools.buildLightweightASTRoot(this.jdtMember);
	}

	public ModifiedDeclaration modifiedDeclaration() {
		return this.modifiedDeclaration(this.astRoot());
	}

	public ModifiedDeclaration modifiedDeclaration(CompilationUnit astRoot) {
		return new ModifiedDeclaration(this.bodyDeclaration(astRoot));
	}

	public ITextRange textRange() {
		return this.textRange(this.lightweightASTRoot());
	}

	public ITextRange textRange(CompilationUnit astRoot) {
		return this.textRange(this.bodyDeclaration(astRoot));
	}
	
	ITextRange textRange(ASTNode astNode) {
		return (astNode == null) ? null : new ASTNodeTextRange(astNode);
	}

	public ITextRange nameTextRange() {
		return this.nameTextRange(this.lightweightASTRoot());
	}
	
	public ITextRange nameTextRange(CompilationUnit astRoot) {
		ISourceRange sourceRange = this.nameSourceRange();
		return
			new SimpleTextRange(
				sourceRange.getOffset(), 
				sourceRange.getLength(),
				astRoot.getLineNumber(sourceRange.getOffset())
			);
	}
	
	private ISourceRange nameSourceRange() {
		try {
			return this.jdtMember.getNameRange();
		} catch (JavaModelException ex) {
			throw new RuntimeException(ex);
		}
	}

	/**
	 * this will throw a NPE for a top-level type
	 */
	TypeDeclaration declaringTypeDeclaration(CompilationUnit astRoot) {
		return this.declaringType.bodyDeclaration(astRoot);
	}

	@Override
	public String toString() {
		return StringTools.buildToStringFor(this, this.getName());
	}


	// ********** abstract methods **********

	/**
	 * Return the member's body declaration.
	 */
	public abstract BodyDeclaration bodyDeclaration(CompilationUnit astRoot);


	// ********** annotations **********

	public Annotation annotation(DeclarationAnnotationAdapter adapter, CompilationUnit astRoot) {
		return adapter.getAnnotation(this.modifiedDeclaration(astRoot));
	}

	public Annotation annotation(DeclarationAnnotationAdapter adapter) {
		return this.annotation(adapter, this.astRoot());
	}

	public boolean containsAnnotation(DeclarationAnnotationAdapter adapter, CompilationUnit astRoot) {
		return this.annotation(adapter, astRoot) != null;
	}

	public boolean containsAnnotation(DeclarationAnnotationAdapter adapter) {
		return this.containsAnnotation(adapter, this.astRoot());
	}

	/**
	 * Return whether the member contains any one of the specified annotations.
	 */
	public boolean containsAnyAnnotation(DeclarationAnnotationAdapter[] adapters) {
		return this.containsAnyAnnotation(adapters, this.astRoot());
	}

	/**
	 * Return whether the member contains any one of the specified annotations.
	 */
	public boolean containsAnyAnnotation(DeclarationAnnotationAdapter[] adapters, CompilationUnit astRoot) {
		for (DeclarationAnnotationAdapter adapter : adapters) {
			if (this.containsAnnotation(adapter, astRoot)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Return the text range corresponding to the specified annotation.
	 * If the annotation is missing, return null.
	 */
	public ITextRange annotationTextRange(DeclarationAnnotationAdapter adapter, CompilationUnit astRoot) {
		return this.textRange(this.annotation(adapter, astRoot));
	}

	/**
	 * Return the text range corresponding to the specified annotation.
	 * If the annotation is missing, return null.
	 */
	public ITextRange annotationTextRange(DeclarationAnnotationAdapter adapter) {
		return this.annotationTextRange(adapter, this.astRoot());
	}

	/**
	 * Return the AST node corresponding to the specified annotation.
	 * If the annotation is missing, return its parent node.
	 */
	public ASTNode annotationASTNode(DeclarationAnnotationAdapter adapter, CompilationUnit astRoot) {
		return adapter.astNode(this.modifiedDeclaration(astRoot));
	}

	/**
	 * Return the AST node corresponding to the specified annotation.
	 * If the annotation is missing, return its parent node.
	 */
	public ASTNode annotationASTNode(DeclarationAnnotationAdapter adapter) {
		return this.annotationASTNode(adapter, this.astRoot());
	}

	/**
	 * Add the specified marker annotation to the member.
	 */
	public void newMarkerAnnotation(final DeclarationAnnotationAdapter adapter) {
		this.edit(new Editor() {
			public void edit(ModifiedDeclaration declaration) {
				adapter.newMarkerAnnotation(declaration);
			}
		});		
	}

	/**
	 * Add the specified single member annotation to the member.
	 */
	public void newSingleMemberAnnotation(final DeclarationAnnotationAdapter adapter) {
		this.edit(new Editor() {
			public void edit(ModifiedDeclaration declaration) {
				adapter.newSingleMemberAnnotation(declaration);
			}
		});		
	}

	/**
	 * Add the specified normal annotation to the member.
	 */
	public void newNormalAnnotation(final DeclarationAnnotationAdapter adapter) {
		this.edit(new Editor() {
			public void edit(ModifiedDeclaration declaration) {
				adapter.newNormalAnnotation(declaration);
			}
		});		
	}

	/**
	 * Remove the specified annotation from the member.
	 */
	public void removeAnnotation(final DeclarationAnnotationAdapter adapter) {
		this.edit(new Editor() {
			public void edit(ModifiedDeclaration declaration) {
				adapter.removeAnnotation(declaration);
			}
		});		
	}


	// ********** annotation elements **********

	public <T> T annotationElementValue(DeclarationAnnotationElementAdapter<T> adapter, CompilationUnit astRoot) {
		return adapter.getValue(this.modifiedDeclaration(astRoot));
	}

	public <T> T annotationElementValue(DeclarationAnnotationElementAdapter<T> adapter) {
		return this.annotationElementValue(adapter, this.astRoot());
	}

	public Expression annotationElementExpression(DeclarationAnnotationElementAdapter<?> adapter, CompilationUnit astRoot) {
		return adapter.expression(this.modifiedDeclaration(astRoot));
	}

	public Expression annotationElementExpression(DeclarationAnnotationElementAdapter<?> adapter) {
		return this.annotationElementExpression(adapter, this.astRoot());
	}

	public boolean containsAnnotationElement(DeclarationAnnotationElementAdapter<?> adapter, CompilationUnit astRoot) {
		return this.annotationElementExpression(adapter, astRoot) != null;
	}

	public boolean containsAnnotationElement(DeclarationAnnotationElementAdapter<?> adapter) {
		return this.containsAnnotationElement(adapter, this.astRoot());
	}

	/**
	 * Return the text range corresponding to the specified element.
	 * If the element is missing, return null.
	 */
	public ITextRange annotationElementTextRange(DeclarationAnnotationElementAdapter<?> adapter, CompilationUnit astRoot) {
		return this.textRange(this.annotationElementExpression(adapter, astRoot));
	}

	/**
	 * Return the text range corresponding to the specified element.
	 * If the element is missing, return null.
	 */
	public ITextRange annotationElementTextRange(DeclarationAnnotationElementAdapter<?> adapter) {
		return this.annotationElementTextRange(adapter, this.astRoot());
	}

	/**
	 * Return the AST node corresponding to the specified element.
	 * If the element is missing, return its parent node.
	 */
	public ASTNode annotationElementASTNode(DeclarationAnnotationElementAdapter<?> adapter, CompilationUnit astRoot) {
		return adapter.astNode(this.modifiedDeclaration(astRoot));
	}

	/**
	 * Return the AST node corresponding to the specified element.
	 * If the element is missing, return its parent node.
	 */
	public ASTNode annotationElementASTNode(DeclarationAnnotationElementAdapter<?> adapter) {
		return this.annotationElementASTNode(adapter, this.astRoot());
	}

	/**
	 * Set the value of the specified element.
	 */
	public <T> void setAnnotationElementValue(final DeclarationAnnotationElementAdapter<T> adapter, final T value) {
		this.edit(new Editor() {
			public void edit(ModifiedDeclaration declaration) {
				adapter.setValue(value, declaration);
			}
		});		
	}


	// ********** editing **********

	/**
	 * Edit the member with the specified editor.
	 * The editor will be invoked once the member's compilation unit
	 * is in an editable state.
	 */
	public void edit(Editor editor) {
		try {
			this.edit_(editor);
		} catch (JavaModelException ex) {
			throw new RuntimeException(ex);
		} catch (BadLocationException ex) {
			throw new RuntimeException(ex);
		}
	}

	/**
	 * NB: Be careful changing this method.
	 * Things to look out for:
	 *     - when editing via the JavaEditor there is no need to create a working copy
	 *     - when editing headlessly, a "working copy" must be created
	 *        (at least as far as I can tell  ~kfm)
	 *     - when editing via a plain text editor, make a working copy or else things are screwed
	 *        up the second time you edit through the Persistence Properties View
	 */
	private void edit_(Editor editor) throws JavaModelException, BadLocationException {
		ICompilationUnit compilationUnit = this.compilationUnit();
		if ( ! compilationUnit.isWorkingCopy()) {
			compilationUnit.becomeWorkingCopy(null);
		}

		ITextFileBuffer buffer = FileBuffers.getTextFileBufferManager().getTextFileBuffer(compilationUnit.getResource().getFullPath(), LocationKind.NORMALIZE);
		boolean sharedDocument = (buffer != null);  // documents are typically shared when they are already open in an editor
		IDocument doc = sharedDocument ?
				buffer.getDocument()
			:
				new Document(compilationUnit.getBuffer().getContents());

		CompilationUnit astRoot = this.astRoot();
		astRoot.recordModifications();

		editor.edit(this.modifiedDeclaration(astRoot));

		TextEdit edits = astRoot.rewrite(doc, compilationUnit.getJavaProject().getOptions(true));
		if (sharedDocument) {
			this.modifySharedDocumentCommandExecutor().execute(new ModifySharedDocumentCommand(edits, doc));
		} else {
			this.applyEdits(edits, doc);
		}

		if ( ! sharedDocument) {
			compilationUnit.getBuffer().setContents(doc.get());
			compilationUnit.commitWorkingCopy(true, null);  // true="force"
			compilationUnit.discardWorkingCopy();
		}
	}

	/**
	 * apply the specified edits to the specified document,
	 * reformatting the document if necessary
	 */
	void applyEdits(TextEdit edits, IDocument doc) throws MalformedTreeException, BadLocationException {
		edits.apply(doc, TextEdit.UPDATE_REGIONS);
		this.annotationEditFormatter().format(doc, edits);
	}

	private AnnotationEditFormatter annotationEditFormatter() {
		return DefaultAnnotationEditFormatter.instance();
	}

	private CommandExecutor modifySharedDocumentCommandExecutor() {
		return this.modifySharedDocumentCommandExecutorProvider.commandExecutor();
	}


	// ********** "editor" interface **********

	/**
	 * This interface defines a callback that is invoked when the member's
	 * compilation unit is in a state to be manipulated.
	 */
	public interface Editor {

		/**
		 * Edit the specified declaration.
		 */
		void edit(ModifiedDeclaration declaration);

	}


	// ********** modify shared document command class **********

	/**
	 * simple command that calls back to the member to apply the edits
	 * in the same way as if the document were not shared
	 */
	class ModifySharedDocumentCommand implements Command {
		private final TextEdit edits;
		private final IDocument doc;

		ModifySharedDocumentCommand(TextEdit edits, IDocument doc) {
			super();
			this.edits = edits;
			this.doc = doc;
		}

		public void execute() {
			try {
				Member.this.applyEdits(this.edits, this.doc);
			} catch (MalformedTreeException ex) {
				throw new RuntimeException(ex);
			} catch (BadLocationException ex) {
				throw new RuntimeException(ex);
			}
		}

	}

}
