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

import junit.framework.Test;
import junit.framework.TestSuite;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.ltk.core.refactoring.RefactoringStatus;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.corext.refactoring.code.IntroduceIndirectionRefactoring;

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

public class IntroduceIndirectionTests extends RefactoringTest {

	private static final Class clazz= IntroduceIndirectionTests.class;
	private static final String REFACTORING_PATH= "IntroduceIndirection/";

	public IntroduceIndirectionTests(String name) {
		super(name);
	}

	protected String getRefactoringPath() {
		return REFACTORING_PATH;
	}

	public static Test suite() {
		return new RefactoringTestSetup(new TestSuite(clazz));
	}

	public static Test setUpTest(Test test) {
		return new RefactoringTestSetup(test);
	}

	/**
	 *
	 * Invokes the introduce indirection ref. Some pointers:
	 *
	 * @param topLevelName This is an array of fully qualified top level(!) type names with exactly one package prefix (e.g. "p.Foo").
	 * 					   Simple names must correspond to .java files.
	 * 					   The first cu will be used for the invocation of the refactoring (see positioning)
	 * @param newName name of indirection method
	 * @param qTypeName qualified type name of the type for the indirection method. Should be one of the cus in topLevelName.
	 * @param startLine starting line of selection in topLevelName[0]
	 * @param startColumn starting column of selection in topLevelName[0]
	 * @param endLine ending line of selection in topLevelName[0]
	 * @param endColumn ending column of selection in topLevelName[0]
	 * @param updateReferences true if references should be updated
	 * @param shouldWarn if true, warnings will be expected in the result
	 * @param shouldError if true, errors will be expected in the result
	 * @param shouldFail if true, fatal errors will be expected in the result
	 * @throws Exception
	 * @throws JavaModelException
	 * @throws CoreException
	 * @throws IOException
	 */
	private void helper(String[] topLevelName, String newName, String qTypeName, int startLine, int startColumn, int endLine, int endColumn, boolean updateReferences, boolean shouldWarn,
			boolean shouldError, boolean shouldFail) throws Exception, JavaModelException, CoreException, IOException {
		ICompilationUnit[] cu= new ICompilationUnit[topLevelName.length];
		for (int i= 0; i < topLevelName.length; i++) {
			String packName= topLevelName[i].substring(0, topLevelName[i].indexOf('.'));
			String className= topLevelName[i].substring(topLevelName[i].indexOf('.') + 1);
			IPackageFragment cPackage= getRoot().createPackageFragment(packName, true, null);
			cu[i]= createCUfromTestFile(cPackage, className);
		}

		ISourceRange selection= TextRangeUtil.getSelection(cu[0], startLine, startColumn, endLine, endColumn);
		try {
			IntroduceIndirectionRefactoring ref= new IntroduceIndirectionRefactoring(cu[0], selection.getOffset(), selection.getLength());
			ref.setEnableUpdateReferences(updateReferences);
			if (qTypeName != null)
				ref.setIntermediaryClassName(qTypeName);
			if (newName != null)
				ref.setIntermediaryMethodName(newName);

			boolean failed= false;
			RefactoringStatus status= performRefactoringWithStatus(ref);
			if (status.hasFatalError()) {
				assertTrue("Failed but shouldn't: " + status.getMessageMatchingSeverity(RefactoringStatus.FATAL), shouldFail);
				failed= true;
			} else
				assertFalse("Didn't fail although expected", shouldFail);

			if (!failed) {

				if (status.hasError())
					assertTrue("Had errors but shouldn't: " + status.getMessageMatchingSeverity(RefactoringStatus.ERROR), shouldError);
				else
					assertFalse("No error although expected", shouldError);

				if (status.hasWarning())
					assertTrue("Had warnings but shouldn't: " + status.getMessageMatchingSeverity(RefactoringStatus.WARNING), shouldWarn);
				else
					assertFalse("No warning although expected", shouldWarn);

				for (int i= 0; i < topLevelName.length; i++) {
					String className= topLevelName[i].substring(topLevelName[i].indexOf('.') + 1);
					assertEqualLines("invalid output.", getFileContents(getOutputTestFileName(className)), cu[i].getSource());
				}
			}
		} finally {
			performDummySearch();
			for (int i= 0; i < topLevelName.length; i++)
				cu[i].delete(true, null);
		}
	}

	protected void helperPass(String[] topLevelName, String newName, String target, int startLine, int startColumn, int endLine, int endColumn) throws Exception {
		helper(topLevelName, newName, target, startLine, startColumn, endLine, endColumn, true, false, false, false);
	}

	protected void helperWarn(String[] topLevelName, String newName, String target, int startLine, int startColumn, int endLine, int endColumn) throws Exception {
		helper(topLevelName, newName, target, startLine, startColumn, endLine, endColumn, true, true, false, false);
	}

	protected void helperErr(String[] topLevelName, String newName, String target, int startLine, int startColumn, int endLine, int endColumn) throws Exception {
		helper(topLevelName, newName, target, startLine, startColumn, endLine, endColumn, true, true, true, false);
	}

	protected void helperFail(String[] topLevelName, String newName, String target, int startLine, int startColumn, int endLine, int endColumn) throws Exception {
		helper(topLevelName, newName, target, startLine, startColumn, endLine, endColumn, true, true, true, true);
	}

	public void test01() throws Exception {
		// very simple test
		helperPass(new String[] { "p.Foo" }, "bar", "p.Foo", 7, 10, 7, 13);
	}

	public void test02() throws Exception {
		// warning if a super call is found
		helperWarn(new String[] { "p.A", "p.B" }, "bar", "p.A", 8, 15, 8, 18);
	}

	public void test03() throws Exception {
		// add imports to target
		helperPass(new String[] { "p.Foo", "p.Bar" }, "bar", "p.Bar", 8, 17, 8, 20);
	}

	public void test04() throws Exception {
		// this qualification with outer type, method declaration is in outer type.
		helperPass(new String[] { "p.Foo" }, "bar", "p.Foo", 10, 17, 10, 20);
	}

	public void test05() throws Exception {
		// this qualification with outer type, method declaration is in
		// super type of outer type
		helperPass(new String[] { "p.Foo", "p.Bar" }, "bar", "p.Foo", 12, 17, 12, 27);
	}

	public void test06() throws Exception {
		// this qualification with the current type, method declaration is
		// in super type of current type
		helperPass(new String[] { "p.Foo", "p.Bar" }, "bar", "p.Foo", 10, 13, 10, 23);
	}

	public void test07() throws Exception {
		// test qualification with anonymous type (=> warning, don't update)
		helperWarn(new String[] { "p.E1" }, "bar", "p.E1", 30, 16, 30, 19);
	}

	public void test08() throws Exception {
		// open hierarchy failure
		helperFail(new String[] { "p.SeaLevel", "p.Eiger", "p.Moench" }, "bar", "p.SeaLevel", 13, 11, 13, 14);
	}

	public void test09() throws Exception {
		// create static intermediary
		helperPass(new String[] { "p.Foo" }, "bar", "p.Foo", 7, 17, 7, 20);
	}

	public void test10() throws Exception {
		// error, method already exists
		helperErr(new String[] { "p.Foo", "p.Bar" }, "foo", "p.Foo", 10, 19, 10, 22);
	}

	public void test11() throws Exception {
		// test name clash with existing argument
		helperPass(new String[] { "p.Foo" }, "bar", "p.Foo", 12, 9, 12, 12);
	}

	public void test12() throws Exception {
		// cannot put the intermediary into an inner non-static type
		helperFail(new String[] { "p.Foo" }, "bar", "p.Foo.Inner", 9, 10, 9, 13);
	}

	public void test13() throws Exception {
		// create intermediary inside nested static types
		helperPass(new String[] { "p.Foo", "p.Bar" }, "bar", "p.Foo.Inner.MoreInner", 13, 10, 13, 13);
	}

	public void test14() throws Exception {
		// raise visibility of target so intermediary sees it.
		helperWarn(new String[] { "p0.Foo", "p1.Bar" }, "bar", "p1.Bar", 8, 18, 8, 23);
	}

	public void test15() throws Exception {
		// raise visibility of intermediary type so
		// existing references see it
		helperWarn(new String[] { "p0.Foo", "p0.Bar", "p1.Third" }, "bar", "p0.Bar", 8, 17, 8, 20);
	}

	public void test16() throws Exception {
		// test non-reference mode with a method invocation selected
		helper(new String[] { "p.Bar", "p.Foo" }, "bar", "p.Bar", 6, 19, 6, 22, false, false, false, false);
	}

	public void test17() throws Exception {
		// generic target method
		helperPass(new String[] { "p.Foo" }, "bar", "p.Foo", 16, 9, 16, 12);
	}

	public void test18() throws Exception {
		// simple test with generic type, unused
		try {
			getRoot().getJavaProject().setOption(JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS_METHOD_TYPE_PARAMETERS, JavaCore.ENABLED);
			helperPass(new String[] { "p.Foo" }, "bar", "p.Foo", 19, 11, 19, 14);
		} finally {
			getRoot().getJavaProject().setOption(JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS_METHOD_TYPE_PARAMETERS, JavaCore.DISABLED);
		}
		
	}

	public void test19() throws Exception {
		// simple test with generic type, used
		helperPass(new String[] { "p.Foo" }, "bar", "p.Foo", 19, 11, 19, 14);
	}

	public void test20() throws Exception {
		// complex case with generic type parameters and method parameters used
		helperPass(new String[] { "p.Foo" }, "bar", "p.Foo", 11, 11, 11, 17);
	}

	public void test21() throws Exception {
		// no call updating if type arguments are used
		helperWarn(new String[] { "p.Foo" }, "bar", "p.Foo", 9, 22, 9, 26);
	}

	public void test22() throws Exception {
		// method using type parameters from enclosing types as well
		helperPass(new String[] { "p.Foo" }, "bar", "p.Foo", 16, 24, 16, 27);
	}

	public void test23() throws Exception {
		// warn about incorrect qualified static calls and don't update them.
		helperWarn(new String[] { "p.Foo" }, "bar", "p.Foo", 11, 25, 11, 28);
	}

	public void test24() throws Exception {
		// assure common super type is used even if the hierarchy branches downwards
		helperPass(new String[] { "p.Foo" }, "bar", "p.Foo", 11, 11, 11, 14);
	}

	public void test25() throws Exception {
		// increase visibility of overridden methods as well
		helperWarn(new String[] { "p0.Foo", "p0.SubFoo", "p1.Bar" }, "bar", "p1.Bar", 8, 20, 8, 23);
	}

	public void test26() throws Exception {
		// ensure exceptions are copied
		helperPass(new String[] { "p.Foo" }, "bar", "p.Foo", 7, 24, 7, 27);
	}

	public void test27() throws Exception {
		// complex visibility adjustment case
		// target method is not inside target type, and is overridden
		// target type must be increased, and all overridden methods must be increased.
		helperWarn(new String[] { "p0.Foo", "p0.RealFoo", "p0.NonOriginalSubFoo", "p0.VerySuperFoo", "p1.Bar" }, "bar", "p1.Bar", 7, 13, 7, 16);
	}

	public void test28() throws Exception {
		// the template for the intermediary must be the method inside the real
		// target (for parameter names and exceptions)
		helperWarn(new String[] { "p.Foo", "p.Bar",}, "bar", "p.Foo", 10, 9, 10, 12);
	}

	public void test29() throws Exception {
		// don't adjust visibility twice
		helperWarn(new String[] { "p0.Test", "p1.Other" }, "bar", "p1.Other", 5, 35, 5, 44);
	}

	public void test30() throws Exception {
		// multiple generic instantiations
		helperPass(new String[] { "p.MultiGenerics" }, "bar", "p.MultiGenerics", 7, 16, 7, 26);
	}

	public void test31() throws Exception {
		// test for bug 127665
		helperPass(new String[] { "p.Test" }, "foo", "p.Test0", 13, 20, 13, 23);
	}	
}
