/*******************************************************************************
 * Copyright (c) 2000, 2006 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.ui.tests.refactoring;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import junit.framework.TestCase;

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

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CheckConditionsOperation;
import org.eclipse.ltk.core.refactoring.CreateChangeOperation;
import org.eclipse.ltk.core.refactoring.IUndoManager;
import org.eclipse.ltk.core.refactoring.PerformChangeOperation;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;

import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.ISourceManipulation;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.TypeNameRequestor;

import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Strings;

import org.eclipse.jdt.ui.tests.refactoring.infra.RefactoringTestPlugin;

public abstract class RefactoringTest extends TestCase {

	private IPackageFragmentRoot fRoot;
	private IPackageFragment fPackageP;
	
	public boolean fIsVerbose= false;
	public boolean fIsPreDeltaTest= false;

	public static final String TEST_PATH_PREFIX= "";

	protected static final String TEST_INPUT_INFIX= "/in/";
	protected static final String TEST_OUTPUT_INFIX= "/out/";
	protected static final String CONTAINER= "src";
	
	protected static final List/*<String>*/ PROJECT_RESOURCE_CHILDREN= Arrays.asList(new String[] {
			".project", ".classpath", ".settings" });
	
	public RefactoringTest(String name) {
		super(name);
	}

	protected void setUp() throws Exception {
		fRoot= RefactoringTestSetup.getDefaultSourceFolder();
		fPackageP= RefactoringTestSetup.getPackageP();
		fIsPreDeltaTest= false;
		
		if (fIsVerbose){
			System.out.println("\n---------------------------------------------");
			System.out.println("\nTest:" + getClass() + "." + getName());
		}	
		RefactoringCore.getUndoManager().flush();
	}

	protected void performDummySearch() throws Exception {
		performDummySearch(getPackageP());
	}	

	/**
	 * Removes contents of {@link #getPackageP()}, of {@link #getRoot()} (except for p) and
	 * of the Java project (except for src and the JRE library).
	 * @throws Exception 
	 */
	protected void tearDown() throws Exception {
		refreshFromLocal();	
		performDummySearch();
			
		if (getPackageP().exists()){		
			tryDeletingAllJavaChildren(getPackageP());
			tryDeletingAllNonJavaChildResources(getPackageP());
		}	
		
		if (getRoot().exists()){
			IJavaElement[] packages= getRoot().getChildren();
			for (int i= 0; i < packages.length; i++){
				try{
					IPackageFragment pack= (IPackageFragment)packages[i];
					if (! pack.equals(getPackageP()) && pack.exists() && ! pack.isReadOnly())
						if (pack.isDefaultPackage())
							pack.delete(true, null);
						else
							pack.getResource().delete(true, null); // also delete packages with subpackages
				}	catch (JavaModelException e){
					//try to delete'em all
					e.printStackTrace();
				}	
			}
		}
		
		restoreTestProject();
	}

	private void restoreTestProject() throws Exception {
		IJavaProject javaProject= getRoot().getJavaProject();
		if (javaProject.exists()) {
			IClasspathEntry srcEntry= getRoot().getRawClasspathEntry();
			IClasspathEntry jreEntry= RefactoringTestSetup.getJRELibrary().getRawClasspathEntry();
			IClasspathEntry[] cpes= javaProject.getRawClasspath();
			ArrayList newCPEs= new ArrayList();
			boolean cpChanged= false;
			for (int i= 0; i < cpes.length; i++) {
				IClasspathEntry cpe= cpes[i];
				if (cpe.equals(srcEntry) || cpe.equals(jreEntry)) {
					newCPEs.add(cpe);
				} else {
					cpChanged= true;
				}
			}
			if (cpChanged) {
				IClasspathEntry[] newCPEsArray= (IClasspathEntry[]) newCPEs.toArray(new IClasspathEntry[newCPEs.size()]);
				javaProject.setRawClasspath(newCPEsArray, null);
			}
		
			Object[] nonJavaResources= javaProject.getNonJavaResources();
			for (int i= 0; i < nonJavaResources.length; i++) {
				Object kid= nonJavaResources[i];
				if (kid instanceof IResource) {
					IResource resource= (IResource) kid;
					if (! PROJECT_RESOURCE_CHILDREN.contains(resource.getName())) {
						try {
							resource.delete(true, null);
						} catch (CoreException e) {
							//try to delete'em all
							e.printStackTrace();
						}
					}
				}
			}
		}
	}

	private void refreshFromLocal() throws CoreException {
		if (getRoot().exists())
			getRoot().getResource().refreshLocal(IResource.DEPTH_INFINITE, null);	
		else if (getPackageP().exists())//don't refresh package if root already refreshed
			getPackageP().getResource().refreshLocal(IResource.DEPTH_INFINITE, null);
	}

	private static void tryDeletingAllNonJavaChildResources(IPackageFragment pack) throws JavaModelException {
		Object[] nonJavaKids= pack.getNonJavaResources();
		for (int i= 0; i < nonJavaKids.length; i++) {
			if (nonJavaKids[i] instanceof IResource) {
				IResource resource= (IResource)nonJavaKids[i];
				try {
					resource.delete(true, null);
				} catch (CoreException e) {
					//try to delete'em all
					e.printStackTrace();
				}
			}
		}
	}

	private static void tryDeletingAllJavaChildren(IPackageFragment pack) throws JavaModelException {
		IJavaElement[] kids= pack.getChildren();
		for (int i= 0; i < kids.length; i++){
			if (kids[i] instanceof ISourceManipulation){
				try{
					if (kids[i].exists() && ! kids[i].isReadOnly())
						((ISourceManipulation)kids[i]).delete(true, null);
				}	catch (JavaModelException e){
					//try to delete'em all
					e.printStackTrace();
				}
			}	
		}
	}

	protected IPackageFragmentRoot getRoot() {
		return fRoot;
	}

	protected IPackageFragment getPackageP() {
		return fPackageP;
	}

	protected final RefactoringStatus performRefactoring(RefactoringDescriptor descriptor) throws Exception {
		Refactoring refactoring= createRefactoring(descriptor);
		return performRefactoring(refactoring);
	}

    protected final Refactoring createRefactoring(RefactoringDescriptor descriptor) throws CoreException {
	    RefactoringStatus status= new RefactoringStatus();
		Refactoring refactoring= descriptor.createRefactoring(status);
		assertNotNull("refactoring should not be null", refactoring);
		assertTrue("status should be ok", status.isOK());
	    return refactoring;
    }

	protected final RefactoringStatus performRefactoring(Refactoring ref) throws Exception {
		return performRefactoring(ref, true);
	}
	
	protected final RefactoringStatus performRefactoring(Refactoring ref, boolean providesUndo) throws Exception {
		performDummySearch();
		IUndoManager undoManager= getUndoManager();
		final CreateChangeOperation create= new CreateChangeOperation(
			new CheckConditionsOperation(ref, CheckConditionsOperation.ALL_CONDITIONS),
			RefactoringStatus.FATAL);
		final PerformChangeOperation perform= new PerformChangeOperation(create);
		perform.setUndoManager(undoManager, ref.getName());
		
		IWorkspace workspace= ResourcesPlugin.getWorkspace();
		if (fIsPreDeltaTest) {
			IResourceChangeListener listener= new IResourceChangeListener() {
				public void resourceChanged(IResourceChangeEvent event) {
					if (create.getConditionCheckingStatus().isOK() &&  perform.changeExecuted()) {
						TestModelProvider.assertTrue(event.getDelta());
					}
				}
			};
			try {
				TestModelProvider.clearDelta();
				workspace.checkpoint(false);
				workspace.addResourceChangeListener(listener);
				executePerformOperation(perform, workspace);
			} finally {
				workspace.removeResourceChangeListener(listener);
			}
		} else {
			executePerformOperation(perform, workspace);
		}
		RefactoringStatus status= create.getConditionCheckingStatus();
		if (!status.isOK())
			return status;
		assertTrue("Change wasn't executed", perform.changeExecuted());
		Change undo= perform.getUndoChange();
		if (providesUndo) {
			assertNotNull("Undo doesn't exist", undo);
			assertTrue("Undo manager is empty", undoManager.anythingToUndo());
		} else {
			assertNull("Undo manager contains undo but shouldn't", undo);
		}
		return null;
	}

	protected void executePerformOperation(final PerformChangeOperation perform, IWorkspace workspace) throws CoreException {
		workspace.run(perform, new NullProgressMonitor());
	}
	
	protected final RefactoringStatus performRefactoringWithStatus(Refactoring ref) throws Exception {
		performDummySearch();
		CreateChangeOperation create= new CreateChangeOperation(
			new CheckConditionsOperation(ref, CheckConditionsOperation.ALL_CONDITIONS),
			RefactoringStatus.FATAL);
		PerformChangeOperation perform= new PerformChangeOperation(create);
		perform.setUndoManager(RefactoringCore.getUndoManager(), ref.getName());
		ResourcesPlugin.getWorkspace().run(perform, new NullProgressMonitor());
		RefactoringStatus status= create.getConditionCheckingStatus();
		if (status.hasFatalError())
			return status;
		assertTrue("Change wasn't executed", perform.changeExecuted());
		return status;
	}
	
	protected final Change performChange(final Refactoring refactoring, boolean storeUndo) throws Exception {
		CreateChangeOperation create= new CreateChangeOperation(refactoring);
		PerformChangeOperation perform= new PerformChangeOperation(create);
		if (storeUndo) {
			perform.setUndoManager(getUndoManager(), refactoring.getName());
		}
		ResourcesPlugin.getWorkspace().run(perform, new NullProgressMonitor());
		assertTrue("Change wasn't executed", perform.changeExecuted());
		return perform.getUndoChange();
	}
	
	protected final Change performChange(final Change change) throws Exception {
		PerformChangeOperation perform= new PerformChangeOperation(change);
		ResourcesPlugin.getWorkspace().run(perform, new NullProgressMonitor());
		assertTrue("Change wasn't executed", perform.changeExecuted());
		return perform.getUndoChange();
	}
	
	protected IUndoManager getUndoManager() {
		IUndoManager undoManager= RefactoringCore.getUndoManager();
		undoManager.flush();
		return undoManager;
	}

	/* ===================  helpers  ================= */
	protected IType getType(ICompilationUnit cu, String name) throws JavaModelException {
		IType[] types= cu.getAllTypes();
		for (int i= 0; i < types.length; i++)
			if (JavaModelUtil.getTypeQualifiedName(types[i]).equals(name) ||
			    types[i].getElementName().equals(name))
				return types[i];
		return null;
	}
	
	/*
	 * subclasses override to inform about the location of their test cases
	 */
	protected String getRefactoringPath() {
		return "";
	}

	/*
	 *  example "RenameType/"
	 */
	protected String getTestPath() {
		return TEST_PATH_PREFIX + getRefactoringPath();
	}

	protected String createTestFileName(String cuName, String infix) {
		return getTestPath() + getName() + infix + cuName + ".java";
	}
	
	protected String getInputTestFileName(String cuName) {
		return createTestFileName(cuName, TEST_INPUT_INFIX);
	}
	
	/*
	 * @param subDirName example "p/" or "org/eclipse/jdt/"
	 */
	protected String getInputTestFileName(String cuName, String subDirName) {
		return createTestFileName(cuName, TEST_INPUT_INFIX + subDirName);
	}

	protected String getOutputTestFileName(String cuName) {
		return createTestFileName(cuName, TEST_OUTPUT_INFIX);
	}
	
	/*
	 * @param subDirName example "p/" or "org/eclipse/jdt/"
	 */
	protected String getOutputTestFileName(String cuName, String subDirName) {
		return createTestFileName(cuName, TEST_OUTPUT_INFIX + subDirName);
	}
	
	protected ICompilationUnit createCUfromTestFile(IPackageFragment pack, String cuName) throws Exception {
		return createCUfromTestFile(pack, cuName, true);
	}
	
	protected ICompilationUnit createCUfromTestFile(IPackageFragment pack, String cuName, String subDirName) throws Exception {
		return createCUfromTestFile(pack, cuName, subDirName, true);
	}
	
	protected ICompilationUnit createCUfromTestFile(IPackageFragment pack, String cuName, boolean input) throws Exception {
		String contents= input 
					? getFileContents(getInputTestFileName(cuName))
					: getFileContents(getOutputTestFileName(cuName));
		return createCU(pack, cuName + ".java", contents);
	}
	
	protected ICompilationUnit createCUfromTestFile(IPackageFragment pack, String cuName, String subDirName, boolean input) throws Exception {
		String contents= input 
			? getFileContents(getInputTestFileName(cuName, subDirName))
			: getFileContents(getOutputTestFileName(cuName, subDirName));
		
		return createCU(pack, cuName + ".java", contents);
	}
	
	protected void printTestDisabledMessage(String explanation){
		System.out.println("\n" +getClass().getName() + "::"+ getName() + " disabled (" + explanation + ")");
	}
	
	//-----------------------
	public static InputStream getStream(String content){
		return new ByteArrayInputStream(content.getBytes());
	}
	
	public static IPackageFragmentRoot getSourceFolder(IJavaProject javaProject, String name) throws JavaModelException{
		IPackageFragmentRoot[] roots= javaProject.getPackageFragmentRoots();
		for (int i= 0; i < roots.length; i++) {
			if (! roots[i].isArchive() && roots[i].getElementName().equals(name))
				return roots[i];
		}
		return null;
	}
	
	public String getFileContents(String fileName) throws IOException {
		return getContents(getFileInputStream(fileName));
	}

	public static String getContents(IFile file) throws IOException, CoreException {
		return getContents(file.getContents());
	}
	
	public static ICompilationUnit createCU(IPackageFragment pack, String name, String contents) throws Exception {
		if (pack.getCompilationUnit(name).exists())
			return pack.getCompilationUnit(name);
		ICompilationUnit cu= pack.createCompilationUnit(name, contents, true, null);
		cu.save(null, true);
		return cu;
	}

	public static String getContents(InputStream in) throws IOException {
		BufferedReader br= new BufferedReader(new InputStreamReader(in));
		
		StringBuffer sb= new StringBuffer(300);
		try {
			int read= 0;
			while ((read= br.read()) != -1)
				sb.append((char) read);
		} finally {
			br.close();
		}
		return sb.toString();
	}

	public static InputStream getFileInputStream(String fileName) throws IOException {
		return RefactoringTestPlugin.getDefault().getTestResourceStream(fileName);
	}

	public static String removeExtension(String fileName) {
		return fileName.substring(0, fileName.lastIndexOf('.'));
	}
	
	public static void performDummySearch(IJavaElement element) throws Exception{
		new SearchEngine().searchAllTypeNames(
			null, 
			SearchPattern.R_EXACT_MATCH, 
			"XXXXXXXXX".toCharArray(), // make sure we search a concrete name. This is faster according to Kent 
			SearchPattern.R_EXACT_MATCH, 
			IJavaSearchConstants.CLASS, 
			SearchEngine.createJavaSearchScope(new IJavaElement[]{element}), 
			new Requestor(), 
			IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, 
			null);
	}
	
	public static IMember[] merge(IMember[] a1, IMember[] a2, IMember[] a3){
		return JavaElementUtil.merge(JavaElementUtil.merge(a1, a2), a3);
	}

	public static IMember[] merge(IMember[] a1, IMember[] a2){
		return JavaElementUtil.merge(a1, a2);
	}
		
	public static IField[] getFields(IType type, String[] names) throws JavaModelException{
		if (names == null )
			return new IField[0];
		Set fields= new HashSet();
		for (int i = 0; i < names.length; i++) {
			IField field= type.getField(names[i]);
			assertTrue("field " + field.getElementName() + " does not exist", field.exists());
			fields.add(field);
		}
		return (IField[]) fields.toArray(new IField[fields.size()]);	
	}

	public static IType[] getMemberTypes(IType type, String[] names) throws JavaModelException{
		if (names == null )
			return new IType[0];
		Set memberTypes= new HashSet();
		for (int i = 0; i < names.length; i++) {
			IType memberType;
			if (names[i].indexOf('.') != -1) {
				String[] path= names[i].split("\\.");
				memberType= type.getType(path[0]);
				for (int j= 1; j < path.length; j++) {
					memberType= memberType.getType(path[j]);
				}
			} else
				memberType= type.getType(names[i]);
			assertTrue("member type " + memberType.getElementName() + " does not exist", memberType.exists());
			memberTypes.add(memberType);
		}
		return (IType[]) memberTypes.toArray(new IType[memberTypes.size()]);	
	}
	
	public static IMethod[] getMethods(IType type, String[] names, String[][] signatures) throws JavaModelException{
		if (names == null || signatures == null)
			return new IMethod[0];
		List methods= new ArrayList(names.length);
		for (int i = 0; i < names.length; i++) {
			IMethod method= type.getMethod(names[i], signatures[i]);
			assertTrue("method " + method.getElementName() + " does not exist", method.exists());
			if (!methods.contains(method))
				methods.add(method);
		}
		return (IMethod[]) methods.toArray(new IMethod[methods.size()]);	
	}

	public static IType[] findTypes(IType[] types, String[] namesOfTypesToPullUp) {
		List found= new ArrayList(types.length);
		for (int i= 0; i < types.length; i++) {
			IType type= types[i];
			for (int j= 0; j < namesOfTypesToPullUp.length; j++) {
				String name= namesOfTypesToPullUp[j];
				if (type.getElementName().equals(name))
					found.add(type);					
			}
		}
		return (IType[]) found.toArray(new IType[found.size()]);
	}
	
	public static IField[] findFields(IField[] fields, String[] namesOfFieldsToPullUp) {
		List found= new ArrayList(fields.length);
		for (int i= 0; i < fields.length; i++) {
			IField field= fields[i];
			for (int j= 0; j < namesOfFieldsToPullUp.length; j++) {
				String name= namesOfFieldsToPullUp[j];
				if (field.getElementName().equals(name))
					found.add(field);					
			}
		}
		return (IField[]) found.toArray(new IField[found.size()]);
	}

	public static IMethod[] findMethods(IMethod[] selectedMethods, String[] namesOfMethods, String[][] signaturesOfMethods){
		List found= new ArrayList(selectedMethods.length);
		for (int i= 0; i < selectedMethods.length; i++) {
			IMethod method= selectedMethods[i];
			String[] paramTypes= method.getParameterTypes();
			for (int j= 0; j < namesOfMethods.length; j++) {
				String methodName= namesOfMethods[j];
				if (! methodName.equals(method.getElementName()))
					continue;
				String[] methodSig= signaturesOfMethods[j];
				if (! areSameSignatures(paramTypes, methodSig))
					continue;
				found.add(method);	
			}
		}
		return (IMethod[]) found.toArray(new IMethod[found.size()]);
	}
	
	private static boolean areSameSignatures(String[] s1, String[] s2){
		if (s1.length != s2.length)
			return false;
		for (int i= 0; i < s1.length; i++) {
			if (! s1[i].equals(s2[i]))
				return false;
		}
		return true;
	}
	
	/**
	 * Line-based version of junit.framework.Assert.assertEquals(String, String)
	 * without considering line delimiters.
	 * @param expected the expected value
	 * @param actual the actual value
	 */
	public static void assertEqualLines(String expected, String actual) {
		assertEqualLines("", expected, actual);
	}
	
	/**
	 * Line-based version of junit.framework.Assert.assertEquals(String, String, String)
	 * without considering line delimiters.
	 * @param message the message
	 * @param expected the expected value
	 * @param actual the actual value
	 */
	public static void assertEqualLines(String message, String expected, String actual) {
		String[] expectedLines= Strings.convertIntoLines(expected);
		String[] actualLines= Strings.convertIntoLines(actual);

		String expected2= (expectedLines == null ? null : Strings.concatenate(expectedLines, "\n"));
		String actual2= (actualLines == null ? null : Strings.concatenate(actualLines, "\n"));
		assertEquals(message, expected2, actual2);		
	}
	
	private static class Requestor extends TypeNameRequestor {
	}
}
