/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.structure;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditGroup;

import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;

import org.eclipse.ltk.core.refactoring.CategorizedTextEditGroup;
import org.eclipse.ltk.core.refactoring.GroupCategorySet;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.refactoring.CompilationUnitChange;

import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;

import org.eclipse.jdt.internal.ui.JavaPlugin;

/**
 * A {@link CompilationUnitRewrite} holds all data structures that are typically
 * required for non-trivial refactorings. All getters are initialized lazily to
 * avoid lengthy processing in
 * {@link org.eclipse.ltk.core.refactoring.Refactoring#checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor)}.
 * <p>
 * Bindings are resolved by default, but can be disabled with <code>setResolveBindings(false)</code>.
 * Statements recovery is enabled by default, but can be disabled with <code>setStatementsRecovery(false)</code>.
 * Bindings recovery is disabled by default, but can be enabled with <code>setBindingRecovery(true)</code>.
 * </p>
 */
public class CompilationUnitRewrite {
	//TODO: add RefactoringStatus fStatus;?
	private ICompilationUnit fCu;
	private List<TextEditGroup> fTextEditGroups= new ArrayList<TextEditGroup>();

	private CompilationUnit fRoot; // lazily initialized
	private ASTRewrite fRewrite; // lazily initialized
	private ImportRewrite fImportRewrite; // lazily initialized
	private ImportRemover fImportRemover; // lazily initialized
	private boolean fResolveBindings= true;
	private boolean fStatementsRecovery= true;
	private boolean fBindingsRecovery= false;
	private final WorkingCopyOwner fOwner;
	private IDocument fRememberContent= null;


	public CompilationUnitRewrite(ICompilationUnit cu) {
		this(null, cu, null);
	}

	public CompilationUnitRewrite(WorkingCopyOwner owner, ICompilationUnit cu) {
		this(owner, cu, null);
	}

	public CompilationUnitRewrite(ICompilationUnit cu, CompilationUnit root) {
		this(null, cu, root);
	}

	public CompilationUnitRewrite(WorkingCopyOwner owner, ICompilationUnit cu, CompilationUnit root) {
		fOwner= owner;
		fCu= cu;
		fRoot= root;
	}

	public void rememberContent() {
		fRememberContent= new Document();
	}


	/**
	 * Controls whether the compiler should provide binding information for the AST
	 * nodes it creates. To be effective, this method must be called before any
	 * of {@link #getRoot()},{@link #getASTRewrite()},
	 * {@link #getImportRemover()}. This method has no effect if the target object
	 * has been created with {@link #CompilationUnitRewrite(ICompilationUnit, CompilationUnit)}.
	 * <p>
	 * Defaults to <b><code>true</code></b> (do resolve bindings).
	 * </p>
	 *
	 * @param resolve
	 *            <code>true</code> if bindings are wanted, and
	 *            <code>false</code> if bindings are not of interest
	 * @see org.eclipse.jdt.core.dom.ASTParser#setResolveBindings(boolean)
	 *      Note: The default value (<code>true</code>) differs from the one of
	 *      the corresponding method in ASTParser.
	 */
	public void setResolveBindings(boolean resolve) {
		fResolveBindings= resolve;
	}

	/**
	 * Controls whether the compiler should perform statements recovery.
	 * To be effective, this method must be called before any
	 * of {@link #getRoot()},{@link #getASTRewrite()},
	 * {@link #getImportRemover()}. This method has no effect if the target object
	 * has been created with {@link #CompilationUnitRewrite(ICompilationUnit, CompilationUnit)}.
	 * <p>
	 * Defaults to <b><code>true</code></b> (do perform statements recovery).
	 * </p>
	 *
	 * @param statementsRecovery whether statements recovery should be performed
	 * @see org.eclipse.jdt.core.dom.ASTParser#setStatementsRecovery(boolean)
	 */
	public void setStatementsRecovery(boolean statementsRecovery) {
		fStatementsRecovery= statementsRecovery;
	}

	/**
	 * Controls whether the compiler should perform bindings recovery.
	 * To be effective, this method must be called before any
	 * of {@link #getRoot()},{@link #getASTRewrite()},
	 * {@link #getImportRemover()}. This method has no effect if the target object
	 * has been created with {@link #CompilationUnitRewrite(ICompilationUnit, CompilationUnit)}.
	 * <p>
	 * Defaults to <b><code>false</code></b> (do not perform bindings recovery).
	 * </p>
	 *
	 * @param bindingsRecovery whether bindings recovery should be performed
	 * @see org.eclipse.jdt.core.dom.ASTParser#setBindingsRecovery(boolean)
	 */
	public void setBindingRecovery(boolean bindingsRecovery) {
		fBindingsRecovery= bindingsRecovery;
	}

	public void clearASTRewrite() {
		fRewrite= null;
		fTextEditGroups= new ArrayList<TextEditGroup>();
	}

	public void clearImportRewrites() {
		fImportRewrite= null;
	}

	public void clearASTAndImportRewrites() {
		clearASTRewrite();
		fImportRewrite= null;
	}

	public CategorizedTextEditGroup createCategorizedGroupDescription(String name, GroupCategorySet set) {
		CategorizedTextEditGroup result= new CategorizedTextEditGroup(name, set);
		fTextEditGroups.add(result);
		return result;
	}

	public TextEditGroup createGroupDescription(String name) {
		TextEditGroup result= new TextEditGroup(name);
		fTextEditGroups.add(result);
		return result;
	}

	/**
	 * Creates a compilation unit change based on the events recorded by this compilation unit
	 * rewrite.
	 * 
	 * @param generateGroups <code>true</code> to generate text edit groups, <code>false</code> otherwise
	 * @return a {@link CompilationUnitChange}, or <code>null</code> for an empty change
	 * @throws CoreException when text buffer acquisition or import rewrite text edit creation fails
	 * @throws IllegalArgumentException when the AST rewrite encounters problems
	 * @since 3.6
	 */
	public CompilationUnitChange createChange(boolean generateGroups) throws CoreException {
		return createChange(generateGroups, null);
	}

	/**
	 * Creates a compilation unit change based on the events recorded by this compilation unit
	 * rewrite.
	 * <p>
	 * DO NOT REMOVE, used in a product.</p>
	 * 
	 * @return a {@link org.eclipse.jdt.core.refactoring.CompilationUnitChange}, or <code>null</code> for an empty change
	 * @throws CoreException when text buffer acquisition or import rewrite text edit creation fails
	 * @throws IllegalArgumentException when the AST rewrite encounters problems
	 * @deprecated since 3.5, replaced by {@link #createChange(boolean)}
	 */
	public org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange createChange() throws CoreException {
		CompilationUnitChange change= createChange(true);
		if (change == null)
			return null;
		return new org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange(change);
	}

	/**
	 * Creates a compilation unit change based on the events recorded by this compilation unit
	 * rewrite.
	 * 
	 * @param generateGroups <code>true</code> to generate text edit groups, <code>false</code>
	 *            otherwise
	 * @param monitor the progress monitor or <code>null</code>
	 * @return a {@link CompilationUnitChange}, or <code>null</code> for an empty change
	 * @throws CoreException when text buffer acquisition or import rewrite text edit creation fails
	 * @throws IllegalArgumentException when the AST rewrite encounters problems
	 */
	public CompilationUnitChange createChange(boolean generateGroups, IProgressMonitor monitor) throws CoreException {
		return createChange(fCu.getElementName(), generateGroups, monitor);
	}

	/**
	 * Creates a compilation unit change based on the events recorded by this compilation unit rewrite.
	 * @param name the name of the change to create
	 * @param generateGroups <code>true</code> to generate text edit groups, <code>false</code> otherwise
	 * @param monitor the progress monitor or <code>null</code>
	 * @return a {@link CompilationUnitChange}, or <code>null</code> for an empty change
	 * @throws CoreException when text buffer acquisition or import rewrite text edit creation fails
	 * @throws IllegalArgumentException when the AST rewrite encounters problems
	 */
	public CompilationUnitChange createChange(String name, boolean generateGroups, IProgressMonitor monitor) throws CoreException {
		CompilationUnitChange cuChange= new CompilationUnitChange(name, fCu);
		MultiTextEdit multiEdit= new MultiTextEdit();
		cuChange.setEdit(multiEdit);
		return attachChange(cuChange, generateGroups, monitor);
	}


	/**
	 * Attaches the changes of this compilation unit rewrite to the given CU Change. The given
	 * change <b>must</b> either have no root edit, or a MultiTextEdit as a root edit.
	 * The edits in the given change <b>must not</b> overlap with the changes of
	 * this compilation unit.
	 *
	 * @param cuChange existing CompilationUnitChange with a MultiTextEdit root or no root at all.
	 * @param generateGroups <code>true</code> to generate text edit groups, <code>false</code> otherwise
	 * @param monitor the progress monitor or <code>null</code>
	 * @return a change combining the changes of this rewrite and the given rewrite, or <code>null</code> for an empty change
	 * @throws CoreException when text buffer acquisition or import rewrite text edit creation fails
	 */
	public CompilationUnitChange attachChange(CompilationUnitChange cuChange, boolean generateGroups, IProgressMonitor monitor) throws CoreException {
		try {
			boolean needsAstRewrite= fRewrite != null; // TODO: do we need something like ASTRewrite#hasChanges() here?
			boolean needsImportRemoval= fImportRemover != null && fImportRemover.hasRemovedNodes();
			boolean needsImportRewrite= fImportRewrite != null && fImportRewrite.hasRecordedChanges() || needsImportRemoval;
			if (!needsAstRewrite && !needsImportRemoval && !needsImportRewrite)
				return null;

			MultiTextEdit multiEdit= (MultiTextEdit) cuChange.getEdit();
			if (multiEdit == null) {
				multiEdit= new MultiTextEdit();
				cuChange.setEdit(multiEdit);
			}

			if (needsAstRewrite) {
				TextEdit rewriteEdit;
				if (fRememberContent != null) {
					rewriteEdit= fRewrite.rewriteAST(fRememberContent, fCu.getJavaProject().getOptions(true));
				} else {
					rewriteEdit= fRewrite.rewriteAST();
				}
				if (!isEmptyEdit(rewriteEdit)) {
					multiEdit.addChild(rewriteEdit);
					if (generateGroups) {
						for (Iterator<TextEditGroup> iter= fTextEditGroups.iterator(); iter.hasNext();) {
							TextEditGroup group= iter.next();
							cuChange.addTextEditGroup(group);
						}
					}
				}
			}
			if (needsImportRemoval) {
				fImportRemover.applyRemoves(getImportRewrite());
			}
			if (needsImportRewrite) {
				TextEdit importsEdit= fImportRewrite.rewriteImports(monitor);
				if (!isEmptyEdit(importsEdit)) {
					multiEdit.addChild(importsEdit);
					String importUpdateName= RefactoringCoreMessages.ASTData_update_imports;
					cuChange.addTextEditGroup(new TextEditGroup(importUpdateName, importsEdit));
				}
			} else {

			}
			if (isEmptyEdit(multiEdit))
				return null;
			return cuChange;
		} finally {
			if (monitor != null)
				monitor.done();
		}
	}

	private static boolean isEmptyEdit(TextEdit edit) {
		return edit.getClass() == MultiTextEdit.class && ! edit.hasChildren();
	}

	public ICompilationUnit getCu() {
		return fCu;
	}

	public CompilationUnit getRoot() {
		if (fRoot == null)
			fRoot= new RefactoringASTParser(AST.JLS3).parse(fCu, fOwner, fResolveBindings, fStatementsRecovery, fBindingsRecovery, null);
		return fRoot;
	}

	public AST getAST() {
		return getRoot().getAST();
	}

	public ASTRewrite getASTRewrite() {
		if (fRewrite == null) {
			fRewrite= ASTRewrite.create(getRoot().getAST());
			if (fRememberContent != null) { // wain until ast rewrite is accessed first
				try {
					fRememberContent.set(fCu.getSource());
				} catch (JavaModelException e) {
					fRememberContent= null;
				}
			}
		}
		return fRewrite;
	}

	public ImportRewrite getImportRewrite() {
		if (fImportRewrite == null) {
			// lazily initialized to avoid lengthy processing in checkInitialConditions(..)
			try {
				/* If bindings are to be resolved, then create the AST, so that
				 * ImportRewrite#setUseContextToFilterImplicitImports(boolean) will be set to true
				 * and ContextSensitiveImportRewriteContext etc. can be used. */
				if (fRoot == null && ! fResolveBindings) {
					fImportRewrite= StubUtility.createImportRewrite(fCu, true);
				} else {
					fImportRewrite= StubUtility.createImportRewrite(getRoot(), true);
				}
			} catch (CoreException e) {
				JavaPlugin.log(e);
				throw new IllegalStateException(e.getMessage()); // like ASTParser#createAST(..) does
			}
		}
		return fImportRewrite;

	}

	public ImportRemover getImportRemover() {
		if (fImportRemover == null) {
			fImportRemover= new ImportRemover(fCu.getJavaProject(), getRoot());
		}
		return fImportRemover;
	}

	public void clearGroupDescriptions() {
		for (Iterator<TextEditGroup> iter= fTextEditGroups.iterator(); iter.hasNext();) {
			TextEditGroup group= iter.next();
			group.clearTextEdits();
		}
	}
}
