/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.model;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.*;

abstract public class CopyMoveTests extends ModifyingResourceTests {
public CopyMoveTests(String name) {
	super(name);
}
/**
 * Attempts to copy the element with optional 
 * forcing. The operation should fail with the failure code.
 */
public void copyNegative(IJavaElement element, IJavaElement destination, IJavaElement sibling, String rename, boolean force, int failureCode) {
	try {
		((ISourceManipulation)element).copy(destination, sibling, rename, force, null);
	} catch (JavaModelException jme) {
		assertTrue("Code not correct for JavaModelException: " + jme, jme.getStatus().getCode() == failureCode);
		return;
	}
	assertTrue("The copy should have failed for: " + element, false);
	return;
}
/**
 * Attempts to copy the elements with optional 
 * forcing. The operation should fail with the failure code.
 */
public void copyNegative(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] renames, boolean force, int failureCode) {
	try {
		getJavaModel().copy(elements, destinations, siblings, renames, force, null);
	} catch (JavaModelException jme) {
		assertTrue("Code not correct for JavaModelException: " + jme, jme.getStatus().getCode() == failureCode);
		return;
	}
	assertTrue("The move should have failed for for multiple elements: ", false);
	return;
}
/**
 * Copies the element to the container with optional rename
 * and forcing. The operation should succeed, so any exceptions
 * encountered are thrown.
 */
public IJavaElement copyPositive(IJavaElement element, IJavaElement container, IJavaElement sibling, String rename, boolean force) throws JavaModelException {
	// if forcing, ensure that a name collision exists
	if (force) {
		IJavaElement collision = generateHandle(element, rename, container);
		assertTrue("Collision does not exist", collision.exists());
	}

	IJavaElement copy;
	try {
		startDeltas();
		
		// copy
	 	((ISourceManipulation) element).copy(container, sibling, rename, force, null);
	
		// ensure the original element still exists
		assertTrue("The original element must still exist", element.exists());
	
		// generate the new element	handle
		copy = generateHandle(element, rename, container);
		assertTrue("Copy should exist", copy.exists());
	
		//ensure correct position
		if (element.getElementType() > IJavaElement.COMPILATION_UNIT) {
			ensureCorrectPositioning((IParent) container, sibling, copy);
		} else {
			if (container.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT) {
			} else {
				// ensure package name is correct
				if (container.getElementName().equals("")) {
					// default package - should be no package decl
					IJavaElement[] children = ((ICompilationUnit) copy).getChildren();
					boolean found = false;
					for (int i = 0; i < children.length; i++) {
						if (children[i] instanceof IPackageDeclaration) {
							found = true;
						}
					}
					assertTrue("Should not find package decl", !found);
				} else {
					IJavaElement[] children = ((ICompilationUnit) copy).getChildren();
					boolean found = false;
					for (int i = 0; i < children.length; i++) {
						if (children[i] instanceof IPackageDeclaration) {
							assertTrue("package declaration incorrect", ((IPackageDeclaration) children[i]).getElementName().equals(container.getElementName()));
							found = true;
						}
					}
					assertTrue("Did not find package decl", found);
				}
			}
		}
		IJavaElementDelta destDelta = getDeltaFor(container, true);
		assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED);
		IJavaElementDelta[] deltas = destDelta.getAddedChildren();
		assertTrue("Added children not correct for element copy", deltas[0].getElement().equals(copy));
	} finally {
		stopDeltas();
	}
	return copy;
}
/**
 * Generates a new handle to the original element in
 * its new container.
 */
public IJavaElement generateHandle(IJavaElement original, String rename, IJavaElement container) {
	String name = original.getElementName();
	if (rename != null) {
		name = rename;
	}
	switch (container.getElementType()) {
		case IJavaElement.PACKAGE_FRAGMENT_ROOT :
			switch (original.getElementType()) {
				case IJavaElement.PACKAGE_FRAGMENT :
					return ((IPackageFragmentRoot) container).getPackageFragment(name);
				default :
					assertTrue("illegal child type", false);
					break;
			}
			break;
		case IJavaElement.PACKAGE_FRAGMENT :
			switch (original.getElementType()) {
				case IJavaElement.COMPILATION_UNIT :
					return ((IPackageFragment) container).getCompilationUnit(name);
				default :
					assertTrue("illegal child type", false);
					break;
			}
			break;
		case IJavaElement.COMPILATION_UNIT :
			switch (original.getElementType()) {
				case IJavaElement.IMPORT_DECLARATION :
					return ((ICompilationUnit) container).getImport(name);
				case IJavaElement.PACKAGE_DECLARATION :
					return ((ICompilationUnit) container).getPackageDeclaration(name);
				case IJavaElement.TYPE :
					if (isMainType(original, container)) {
						//the cu has been renamed as well
						container = ((IPackageFragment) container.getParent()).getCompilationUnit(name + ".java");
					}
					return ((ICompilationUnit) container).getType(name);
				default :
					assertTrue("illegal child type", false);
					break;
			}
			break;
		case IJavaElement.TYPE :
			switch (original.getElementType()) {
				case IJavaElement.METHOD :
					if (name.equals(original.getParent().getElementName())) {
						//method is a constructor
						return ((IType) container).getMethod(container.getElementName(), ((IMethod) original).getParameterTypes());
					} else {
						return ((IType) container).getMethod(name, ((IMethod) original).getParameterTypes());
					}
				case IJavaElement.FIELD :
					return ((IType) container).getField(name);
				case IJavaElement.TYPE :
					return ((IType) container).getType(name);
				case IJavaElement.INITIALIZER :
					//hack to return the first initializer
					return ((IType) container).getInitializer(1);
				default :
					assertTrue("illegal child type", false);
					break;
			}
			break;
		default :
			assertTrue("unsupported container type", false);
			break;
	}
	assertTrue("should not get here", false);
	return null;
}
/**
 * Returns true if this element is the main type of its compilation unit.
 */
protected boolean isMainType(IJavaElement element, IJavaElement parent) {
	if (parent instanceof ICompilationUnit) {
		if (element instanceof IType) {
			ICompilationUnit cu= (ICompilationUnit)parent;
			String typeName = cu.getElementName();
			typeName = typeName.substring(0, typeName.length() - 5);
			return element.getElementName().equals(typeName) && element.getParent().equals(cu);
		}
	}
	return false;
}
/**
 * Attempts to move the element with optional 
 * forcing. The operation should fail with the failure code.
 */
public void moveNegative(IJavaElement element, IJavaElement destination, IJavaElement sibling, String rename, boolean force, int failureCode) {
	try {
		((ISourceManipulation)element).move(destination, sibling, rename, force, null);
	} catch (JavaModelException jme) {
		assertTrue("Code not correct for JavaModelException: " + jme, jme.getStatus().getCode() == failureCode);
		return;
	}
	assertTrue("The move should have failed for: " + element, false);
	return;
}
/**
 * Attempts to move the element with optional 
 * forcing. The operation should fail with the failure code.
 */
public void moveNegative(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] renames, boolean force, int failureCode) {
	try {
		getJavaModel().move(elements, destinations, siblings, renames, force, null);
	} catch (JavaModelException jme) {
		assertTrue("Code not correct for JavaModelException: " + jme, jme.getStatus().getCode() == failureCode);
		return;
	}
	assertTrue("The move should have failed for for multiple elements: ", false);
	return;
}
/**
 * Moves the element to the container with optional rename
 * and forcing. The operation should succeed, so any exceptions
 * encountered are thrown.
 */
public void movePositive(IJavaElement element, IJavaElement container, IJavaElement sibling, String rename, boolean force) throws JavaModelException {
	IJavaElement[] siblings = new IJavaElement[] {sibling};
	String[] renamings = new String[] {rename};
	if (sibling == null) {
		siblings = null;
	}
	if (rename == null) {
		renamings = null;
	}
	movePositive(new IJavaElement[] {element}, new IJavaElement[] {container}, siblings, renamings, force);
}
/**
 * Moves the elements to the containers with optional renaming
 * and forcing. The operation should succeed, so any exceptions
 * encountered are thrown.
 */
public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force) throws JavaModelException {
	movePositive(elements, destinations, siblings, names, force, null);
}
/**
 * Moves the elements to the containers with optional renaming
 * and forcing. The operation should succeed, so any exceptions
 * encountered are thrown.
 */
public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force, IProgressMonitor monitor) throws JavaModelException {
	// if forcing, ensure that a name collision exists
	int i;
	if (force) {
		for (i = 0; i < elements.length; i++) {
			IJavaElement e = elements[i];
			IJavaElement collision = null;
			if (names == null) {
				collision = generateHandle(e, null, destinations[i]);
			} else {
				collision = generateHandle(e, names[i], destinations[i]);
			}
			assertTrue("Collision does not exist", collision.exists());
		}
	}

	try {
		startDeltas();
		
		// move
		getJavaModel().move(elements, destinations, siblings, names, force, monitor);
		for (i = 0; i < elements.length; i++) {
			IJavaElement element = elements[i];
			IJavaElement moved = null;
			if (names == null) {
				moved = generateHandle(element, null, destinations[i]);
			} else {
				moved = generateHandle(element, names[i], destinations[i]);
			}
			// ensure the original element no longer exists, unless moving within the same container
			if (!destinations[i].equals(element.getParent())) {
				if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
					//moving a package fragment does not necessary mean that it no longer exists
					//it could have members that are not part of the Java Model
					try {
						IResource[] members = ((IContainer) element.getUnderlyingResource()).members();
						if (members.length == 0) {
							assertTrue("The original element must not exist", !element.exists());
						}
					} catch (CoreException ce) {
						throw new JavaModelException(ce);
					}
				} else {
					assertTrue("The original element must not exist", !element.exists());
				}
			}
			assertTrue("Moved element should exist", moved.exists());
	
			//ensure correct position
			if (element.getElementType() > IJavaElement.COMPILATION_UNIT) {
				if (siblings != null && siblings.length > 0) {
					ensureCorrectPositioning((IParent) moved.getParent(), siblings[i], moved);
				}
			} else {
				IJavaElement container = destinations[i];
				if (container.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT) {
				} else { // ensure package name is correct
	
					if (container.getElementName().equals("")) {
						// default package - should be no package decl
						IJavaElement[] children = ((ICompilationUnit) moved).getChildren();
						boolean found = false;
						for (int j = 0; j < children.length; j++) {
							if (children[j] instanceof IPackageDeclaration) {
								found = true;
								break;
							}
						}
						assertTrue("Should not find package decl", !found);
					} else {
						IJavaElement[] children = ((ICompilationUnit) moved).getChildren();
						boolean found = false;
						for (int j = 0; j < children.length; j++) {
							if (children[j] instanceof IPackageDeclaration) {
								assertTrue("package declaration incorrect", ((IPackageDeclaration) children[j]).getElementName().equals(container.getElementName()));
								found = true;
								break;
							}
						}
						assertTrue("Did not find package decl", found);
					}
				}
			}
			IJavaElementDelta destDelta = null;
			if (isMainType(element, destinations[i]) && names != null && names[i] != null) { //moved/renamed main type to same cu
				destDelta = getDeltaFor(moved.getParent());
				assertTrue("Renamed compilation unit as result of main type not added", destDelta != null && destDelta.getKind() == IJavaElementDelta.ADDED);
				assertTrue("flag should be F_MOVED_FROM", (destDelta.getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0);
				assertTrue("moved from handle should be original", destDelta.getMovedFromElement().equals(element.getParent()));
			} else {
				destDelta = getDeltaFor(destinations[i], true);
				assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED);
				IJavaElementDelta[] deltas = destDelta.getAddedChildren();
				assertTrue("Added children not correct for element copy", deltas[i].getElement().equals(moved));
				assertTrue("should be K_ADDED", deltas[i].getKind() == IJavaElementDelta.ADDED);
				IJavaElementDelta sourceDelta= getDeltaFor(element, false);
				assertTrue("should be K_REMOVED", sourceDelta.getKind() == IJavaElementDelta.REMOVED);
			}
		}
	} finally {
		stopDeltas();
	}
}
}
