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

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.*;

/**
 * This class is used to perform operations on multiple <code>IJavaElement</code>.
 * It is responible for running each operation in turn, collecting
 * the errors and merging the corresponding <code>JavaElementDelta</code>s.
 * <p>
 * If several errors occured, they are collected in a multi-status
 * <code>JavaModelStatus</code>. Otherwise, a simple <code>JavaModelStatus</code>
 * is thrown.
 */
public abstract class MultiOperation extends JavaModelOperation {
	/**
	 * Table specifying insertion positions for elements being 
	 * copied/moved/renamed. Keyed by elements being processed, and
	 * values are the corresponding insertion point.
	 * @see #processElements()
	 */
	protected Map insertBeforeElements = new HashMap(1);
	/**
	 * Table specifying the new parent for elements being 
	 * copied/moved/renamed.
	 * Keyed by elements being processed, and
	 * values are the corresponding destination parent.
	 */
	protected Map newParents;
	/**
	 * This table presents the data in <code>fRenamingList</code> in a more
	 * convenient way.
	 */
	protected Map renamings;
	/**
	 * The list of renamings supplied to the operation
	 */
	protected String[] renamingsList = null;
	/**
	 * Creates a new <code>MultiOperation</code> on <code>elementsToProcess</code>.
	 */
	protected MultiOperation(IJavaElement[] elementsToProcess, boolean force) {
		super(elementsToProcess, force);
	}
	/**
	 * Creates a new <code>MultiOperation</code>.
	 */
	protected MultiOperation(IJavaElement[] elementsToProcess, IJavaElement[] parentElements, boolean force) {
		super(elementsToProcess, parentElements, force);
		this.newParents = new HashMap(elementsToProcess.length);
		if (elementsToProcess.length == parentElements.length) {
			for (int i = 0; i < elementsToProcess.length; i++) {
				this.newParents.put(elementsToProcess[i], parentElements[i]);
			}
		} else { //same destination for all elements to be moved/copied/renamed
			for (int i = 0; i < elementsToProcess.length; i++) {
				this.newParents.put(elementsToProcess[i], parentElements[0]);
			}
		}
	
	}
	/**
	 * Convenience method to create a <code>JavaModelException</code>
	 * embending a <code>JavaModelStatus</code>.
	 */
	protected void error(int code, IJavaElement element) throws JavaModelException {
		throw new JavaModelException(new JavaModelStatus(code, element));
	}
	/**
	 * Executes the operation.
	 *
	 * @exception JavaModelException if one or several errors occured during the operation.
	 * If multiple errors occured, the corresponding <code>JavaModelStatus</code> is a
	 * multi-status. Otherwise, it is a simple one.
	 */
	protected void executeOperation() throws JavaModelException {
		processElements();
	}
	/**
	 * Returns the parent of the element being copied/moved/renamed.
	 */
	protected IJavaElement getDestinationParent(IJavaElement child) {
		return (IJavaElement)this.newParents.get(child);
	}
	/**
	 * Returns the name to be used by the progress monitor.
	 */
	protected abstract String getMainTaskName();
	/**
	 * Returns the new name for <code>element</code>, or <code>null</code>
	 * if there are no renamings specified.
	 */
	protected String getNewNameFor(IJavaElement element) throws JavaModelException {
		String newName = null;
		if (this.renamings != null)
			newName = (String) this.renamings.get(element);
		if (newName == null && element instanceof IMethod && ((IMethod) element).isConstructor())
			newName = getDestinationParent(element).getElementName();
		return newName;
	}
	/**
	 * Sets up the renamings hashtable - keys are the elements and
	 * values are the new name.
	 */
	private void initializeRenamings() {
		if (this.renamingsList != null && this.renamingsList.length == this.elementsToProcess.length) {
			this.renamings = new HashMap(this.renamingsList.length);
			for (int i = 0; i < this.renamingsList.length; i++) {
				if (this.renamingsList[i] != null) {
					this.renamings.put(this.elementsToProcess[i], this.renamingsList[i]);
				}
			}
		}
	}
	/**
	 * Returns <code>true</code> if this operation represents a move or rename, <code>false</code>
	 * if this operation represents a copy.<br>
	 * Note: a rename is just a move within the same parent with a name change.
	 */
	protected boolean isMove() {
		return false;
	}
	/**
	 * Returns <code>true</code> if this operation represents a rename, <code>false</code>
	 * if this operation represents a copy or move.
	 */
	protected boolean isRename() {
		return false;
	}
	
	/**
	 * Subclasses must implement this method to process a given <code>IJavaElement</code>.
	 */
	protected abstract void processElement(IJavaElement element) throws JavaModelException;
	/**
	 * Processes all the <code>IJavaElement</code>s in turn, collecting errors
	 * and updating the progress monitor.
	 *
	 * @exception JavaModelException if one or several operation(s) was unable to
	 * be completed.
	 */
	protected void processElements() throws JavaModelException {
		beginTask(getMainTaskName(), this.elementsToProcess.length);
		IJavaModelStatus[] errors = new IJavaModelStatus[3];
		int errorsCounter = 0;
		for (int i = 0; i < this.elementsToProcess.length; i++) {
			try {
				verify(this.elementsToProcess[i]);
				processElement(this.elementsToProcess[i]);
			} catch (JavaModelException jme) {
				if (errorsCounter == errors.length) {
					// resize
					System.arraycopy(errors, 0, (errors = new IJavaModelStatus[errorsCounter*2]), 0, errorsCounter);
				}
				errors[errorsCounter++] = jme.getJavaModelStatus();
			} finally {
				worked(1);
			}
		}
		done();
		if (errorsCounter == 1) {
			throw new JavaModelException(errors[0]);
		} else if (errorsCounter > 1) {
			if (errorsCounter != errors.length) {
				// resize
				System.arraycopy(errors, 0, (errors = new IJavaModelStatus[errorsCounter]), 0, errorsCounter);
			}
			throw new JavaModelException(JavaModelStatus.newMultiStatus(errors));
		}
	}
	/**
	 * Sets the insertion position in the new container for the modified element. The element
	 * being modified will be inserted before the specified new sibling. The given sibling
	 * must be a child of the destination container specified for the modified element.
	 * The default is <code>null</code>, which indicates that the element is to be
	 * inserted at the end of the container.
	 */
	public void setInsertBefore(IJavaElement modifiedElement, IJavaElement newSibling) {
		this.insertBeforeElements.put(modifiedElement, newSibling);
	}
	/**
	 * Sets the new names to use for each element being copied. The renamings
	 * correspond to the elements being processed, and the number of
	 * renamings must match the number of elements being processed.
	 * A <code>null</code> entry in the list indicates that an element
	 * is not to be renamed.
	 *
	 * <p>Note that some renamings may not be used.  If both a parent
	 * and a child have been selected for copy/move, only the parent
	 * is changed.  Therefore, if a new name is specified for the child,
	 * the child's name will not be changed.
	 */
	public void setRenamings(String[] renamingsList) {
		this.renamingsList = renamingsList;
		initializeRenamings();
	}
	/**
	 * This method is called for each <code>IJavaElement</code> before
	 * <code>processElement</code>. It should check that this <code>element</code>
	 * can be processed.
	 */
	protected abstract void verify(IJavaElement element) throws JavaModelException;
	/**
	 * Verifies that the <code>destination</code> specified for the <code>element</code> is valid for the types of the
	 * <code>element</code> and <code>destination</code>.
	 */
	protected void verifyDestination(IJavaElement element, IJavaElement destination) throws JavaModelException {
		if (destination == null || !destination.exists())
			error(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, destination);
		
		int destType = destination.getElementType();
		switch (element.getElementType()) {
			case IJavaElement.PACKAGE_DECLARATION :
			case IJavaElement.IMPORT_DECLARATION :
				if (destType != IJavaElement.COMPILATION_UNIT)
					error(IJavaModelStatusConstants.INVALID_DESTINATION, element);
				break;
			case IJavaElement.TYPE :
				if (destType != IJavaElement.COMPILATION_UNIT && destType != IJavaElement.TYPE)
					error(IJavaModelStatusConstants.INVALID_DESTINATION, element);
				break;
			case IJavaElement.METHOD :
			case IJavaElement.FIELD :
			case IJavaElement.INITIALIZER :
				if (destType != IJavaElement.TYPE || destination instanceof BinaryType)
					error(IJavaModelStatusConstants.INVALID_DESTINATION, element);
				break;
			case IJavaElement.COMPILATION_UNIT :
				if (destType != IJavaElement.PACKAGE_FRAGMENT)
					error(IJavaModelStatusConstants.INVALID_DESTINATION, element);
				else {
					CompilationUnit cu = (CompilationUnit)element;
					if (isMove() && cu.isWorkingCopy() && !cu.isPrimary())
						error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
				}
				break;
			case IJavaElement.PACKAGE_FRAGMENT :
				IPackageFragment fragment = (IPackageFragment) element;
				IJavaElement parent = fragment.getParent();
				if (parent.isReadOnly())
					error(IJavaModelStatusConstants.READ_ONLY, element);
				else if (destType != IJavaElement.PACKAGE_FRAGMENT_ROOT)
					error(IJavaModelStatusConstants.INVALID_DESTINATION, element);
				break;
			default :
				error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
		}
	}
	/**
	 * Verify that the new name specified for <code>element</code> is
	 * valid for that type of Java element.
	 */
	protected void verifyRenaming(IJavaElement element) throws JavaModelException {
		String newName = getNewNameFor(element);
		boolean isValid = true;
	
		switch (element.getElementType()) {
			case IJavaElement.PACKAGE_FRAGMENT :
				if (((IPackageFragment) element).isDefaultPackage()) {
					// don't allow renaming of default package (see PR #1G47GUM)
					throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, element));
				}
				isValid = JavaConventions.validatePackageName(newName).getSeverity() != IStatus.ERROR;
				break;
			case IJavaElement.COMPILATION_UNIT :
				isValid = JavaConventions.validateCompilationUnitName(newName).getSeverity() != IStatus.ERROR;
				break;
			case IJavaElement.INITIALIZER :
				isValid = false; //cannot rename initializers
				break;
			default :
				isValid = JavaConventions.validateIdentifier(newName).getSeverity() != IStatus.ERROR;
				break;
		}
	
		if (!isValid) {
			throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_NAME, element, newName));
		}
	}
	/**
	 * Verifies that the positioning sibling specified for the <code>element</code> is exists and
	 * its parent is the destination container of this <code>element</code>.
	 */
	protected void verifySibling(IJavaElement element, IJavaElement destination) throws JavaModelException {
		IJavaElement insertBeforeElement = (IJavaElement) this.insertBeforeElements.get(element);
		if (insertBeforeElement != null) {
			if (!insertBeforeElement.exists() || !insertBeforeElement.getParent().equals(destination)) {
				error(IJavaModelStatusConstants.INVALID_SIBLING, insertBeforeElement);
			}
		}
	}
}
