/*******************************************************************************
 * Copyright (c) 2000, 2008 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.wst.jsdt.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.wst.jsdt.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(IJavaScriptElement element, IJavaScriptElement destination, IJavaScriptElement sibling, String rename, boolean force, int failureCode) {
	try {
		((ISourceManipulation)element).copy(destination, sibling, rename, force, null);
	} catch (JavaScriptModelException jme) {
		assertTrue("Code not correct for JavaScriptModelException: " + 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(IJavaScriptElement[] elements, IJavaScriptElement[] destinations, IJavaScriptElement[] siblings, String[] renames, boolean force, int failureCode) {
	try {
		getJavaModel().copy(elements, destinations, siblings, renames, force, null);
	} catch (JavaScriptModelException jme) {
		assertTrue("Code not correct for JavaScriptModelException: " + 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 IJavaScriptElement copyPositive(IJavaScriptElement element, IJavaScriptElement container, IJavaScriptElement sibling, String rename, boolean force) throws JavaScriptModelException {
	// if forcing, ensure that a name collision exists
	if (force) {
		IJavaScriptElement collision = generateHandle(element, rename, container);
		assertTrue("Collision does not exist", collision.exists());
	}

	IJavaScriptElement 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() > IJavaScriptElement.JAVASCRIPT_UNIT) {
			ensureCorrectPositioning((IParent) container, sibling, copy);
		} else {
			if (container.getElementType() == IJavaScriptElement.PACKAGE_FRAGMENT_ROOT) {
			} else {
				// ensure package name is correct
				if (container.getElementName().equals("")) {
					// default package - should be no package decl
					IJavaScriptElement[] children = ((IJavaScriptUnit) 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 {
					IJavaScriptElement[] children = ((IJavaScriptUnit) 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);
				}
			}
		}
		if (copy.getElementType() == IJavaScriptElement.IMPORT_DECLARATION)
			container = ((IJavaScriptUnit) container).getImportContainer();
		IJavaScriptElementDelta destDelta = getDeltaFor(container, true);
		assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaScriptElementDelta.CHANGED);
		IJavaScriptElementDelta[] 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 IJavaScriptElement generateHandle(IJavaScriptElement original, String rename, IJavaScriptElement container) {
	String name = original.getElementName();
	if (rename != null) {
		name = rename;
	}
	switch (container.getElementType()) {
		case IJavaScriptElement.PACKAGE_FRAGMENT_ROOT :
			switch (original.getElementType()) {
				case IJavaScriptElement.PACKAGE_FRAGMENT :
					return ((IPackageFragmentRoot) container).getPackageFragment(name);
				default :
					assertTrue("illegal child type", false);
					break;
			}
			break;
		case IJavaScriptElement.PACKAGE_FRAGMENT :
			switch (original.getElementType()) {
				case IJavaScriptElement.JAVASCRIPT_UNIT :
					return ((IPackageFragment) container).getJavaScriptUnit(name);
				default :
					assertTrue("illegal child type", false);
					break;
			}
			break;
		case IJavaScriptElement.JAVASCRIPT_UNIT :
			switch (original.getElementType()) {
				case IJavaScriptElement.IMPORT_DECLARATION :
					return ((IJavaScriptUnit) container).getImport(name);
				case IJavaScriptElement.PACKAGE_DECLARATION :
					return ((IJavaScriptUnit) container).getPackageDeclaration(name);
				case IJavaScriptElement.TYPE :
					if (isMainType(original, container)) {
						//the cu has been renamed as well
						container = ((IPackageFragment) container.getParent()).getJavaScriptUnit(name + ".js");
					}
					return ((IJavaScriptUnit) container).getType(name);
				default :
					assertTrue("illegal child type", false);
					break;
			}
			break;
		case IJavaScriptElement.TYPE :
			switch (original.getElementType()) {
				case IJavaScriptElement.METHOD :
					if (name.equals(original.getParent().getElementName())) {
						//method is a constructor
						return ((IType) container).getFunction(container.getElementName(), ((IFunction) original).getParameterTypes());
					}
					return ((IType) container).getFunction(name, ((IFunction) original).getParameterTypes());
				case IJavaScriptElement.FIELD :
					return ((IType) container).getField(name);
				case IJavaScriptElement.TYPE :
					return ((IType) container).getType(name);
				case IJavaScriptElement.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(IJavaScriptElement element, IJavaScriptElement parent) {
	if (parent instanceof IJavaScriptUnit) {
		if (element instanceof IType) {
			IJavaScriptUnit cu= (IJavaScriptUnit)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(IJavaScriptElement element, IJavaScriptElement destination, IJavaScriptElement sibling, String rename, boolean force, int failureCode) {
	try {
		((ISourceManipulation)element).move(destination, sibling, rename, force, null);
	} catch (JavaScriptModelException jme) {
		assertTrue("Code not correct for JavaScriptModelException: " + 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(IJavaScriptElement[] elements, IJavaScriptElement[] destinations, IJavaScriptElement[] siblings, String[] renames, boolean force, int failureCode) {
	try {
		getJavaModel().move(elements, destinations, siblings, renames, force, null);
	} catch (JavaScriptModelException jme) {
		assertTrue("Code not correct for JavaScriptModelException: " + 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(IJavaScriptElement element, IJavaScriptElement container, IJavaScriptElement sibling, String rename, boolean force) throws JavaScriptModelException {
	IJavaScriptElement[] siblings = new IJavaScriptElement[] {sibling};
	String[] renamings = new String[] {rename};
	if (sibling == null) {
		siblings = null;
	}
	if (rename == null) {
		renamings = null;
	}
	movePositive(new IJavaScriptElement[] {element}, new IJavaScriptElement[] {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(IJavaScriptElement[] elements, IJavaScriptElement[] destinations, IJavaScriptElement[] siblings, String[] names, boolean force) throws JavaScriptModelException {
	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(IJavaScriptElement[] elements, IJavaScriptElement[] destinations, IJavaScriptElement[] siblings, String[] names, boolean force, IProgressMonitor monitor) throws JavaScriptModelException {
	// if forcing, ensure that a name collision exists
	int i;
	if (force) {
		for (i = 0; i < elements.length; i++) {
			IJavaScriptElement e = elements[i];
			IJavaScriptElement 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++) {
			IJavaScriptElement element = elements[i];
			IJavaScriptElement 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() == IJavaScriptElement.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 JavaScriptModelException(ce);
					}
				} else {
					assertTrue("The original element must not exist", !element.exists());
				}
			}
			assertTrue("Moved element should exist", moved.exists());
	
			//ensure correct position
			if (element.getElementType() > IJavaScriptElement.JAVASCRIPT_UNIT) {
				if (siblings != null && siblings.length > 0) {
					ensureCorrectPositioning((IParent) moved.getParent(), siblings[i], moved);
				}
			} else {
				IJavaScriptElement container = destinations[i];
				if (container.getElementType() == IJavaScriptElement.PACKAGE_FRAGMENT_ROOT) {
				} else { // ensure package name is correct
	
					if (container.getElementName().equals("")) {
						// default package - should be no package decl
						IJavaScriptElement[] children = ((IJavaScriptUnit) 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 {
						IJavaScriptElement[] children = ((IJavaScriptUnit) 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);
					}
				}
			}
			IJavaScriptElementDelta 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() == IJavaScriptElementDelta.ADDED);
				assertTrue("flag should be F_MOVED_FROM", (destDelta.getFlags() & IJavaScriptElementDelta.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() == IJavaScriptElementDelta.CHANGED);
				IJavaScriptElementDelta[] deltas = destDelta.getAddedChildren();
				assertTrue("Added children not correct for element copy", deltas[i].getElement().equals(moved));
				assertTrue("should be K_ADDED", deltas[i].getKind() == IJavaScriptElementDelta.ADDED);
				IJavaScriptElementDelta sourceDelta= getDeltaFor(element, false);
				assertTrue("should be K_REMOVED", sourceDelta.getKind() == IJavaScriptElementDelta.REMOVED);
			}
		}
	} finally {
		stopDeltas();
	}
}
}
