/*******************************************************************************
 * Copyright (c) 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
 *
 * This is an implementation of an early-draft specification developed under the Java
 * Community Process (JCP) and is made available for testing and evaluation purposes
 * only. The code is not compatible with any specification of the JCP.
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.text.tests;

import java.util.Arrays;
import java.util.Comparator;

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

import org.eclipse.jdt.testplugin.JavaProjectHelper;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;

import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.tests.core.Java17ProjectTestSetup;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
import org.eclipse.jdt.internal.ui.search.ExceptionOccurrencesFinder;
import org.eclipse.jdt.internal.ui.search.IOccurrencesFinder;
import org.eclipse.jdt.internal.ui.search.IOccurrencesFinder.OccurrenceLocation;
import org.eclipse.jdt.internal.ui.search.MethodExitsFinder;

/**
 * Tests the Java Editor's occurrence marking feature.
 */
public class MarkOccurrenceTest17 extends TestCase {
	private static final Class THIS= MarkOccurrenceTest17.class;

	public static Test suite() {
		return new Java17ProjectTestSetup(new TestSuite(THIS));
	}

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

	private ASTParser fParser;

	private IOccurrencesFinder fFinder;

	private IJavaProject fJProject1;

	private IPackageFragmentRoot fSourceFolder;

	/*
	 * @see junit.framework.TestCase#setUp()
	 */
	protected void setUp() throws Exception {
		fParser= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);

		fJProject1= Java17ProjectTestSetup.getProject();
		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
		JavaPlugin.getDefault().getPreferenceStore().setValue(PreferenceConstants.EDITOR_MARK_OCCURRENCES, true);
		JavaPlugin.getDefault().getPreferenceStore().setValue(PreferenceConstants.EDITOR_MARK_IMPLEMENTORS, true);
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#tearDown()
	 */
	protected void tearDown() throws Exception {
		JavaProjectHelper.clear(fJProject1, Java17ProjectTestSetup.getDefaultClasspath());
	}

	private OccurrenceLocation[] getHighlights(StringBuffer source, int offset, int length) throws Exception {
		CompilationUnit root= createCompilationUnit(source);
		String errorString= fFinder.initialize(root, offset, length);
		assertNull(errorString, errorString);
		return fFinder.getOccurrences();
	}

	private CompilationUnit createCompilationUnit(StringBuffer source) throws JavaModelException {
		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
		ICompilationUnit cu= pack1.createCompilationUnit("E.java", source.toString(), false, null);
		fParser.setSource(cu);
		fParser.setResolveBindings(true);
		return (CompilationUnit)fParser.createAST(null);
	}

	private void checkSelection(StringBuffer s, int offset, int length, OccurrenceLocation[] expected) throws Exception {
		OccurrenceLocation[] selectedNodes= getHighlights(s, offset, length);
		assertEquals("number of selections", expected.length, selectedNodes.length);
		sortByStartIndex(selectedNodes);
		sortByStartIndex(expected);
		for (int i= 0; i < selectedNodes.length; i++) {
			assertEquals(expected[i].getOffset(), selectedNodes[i].getOffset());
			assertEquals(expected[i].getLength(), selectedNodes[i].getLength());
		}
	}

	private void sortByStartIndex(OccurrenceLocation[] OccurrenceLocations) {
		Arrays.sort(OccurrenceLocations, new Comparator() {
			public int compare(Object arg0, Object arg1) {
				OccurrenceLocation node0= (OccurrenceLocation)arg0;
				OccurrenceLocation node1= (OccurrenceLocation)arg1;
				return node0.getOffset() - node1.getOffset();
			}
		});
	}

	//pattern must be found - otherwise it's assumed to be an error
	private OccurrenceLocation find(StringBuffer s, String pattern, int ithOccurrence) {
		if (ithOccurrence < 1)
			throw new IllegalStateException("ithOccurrence = " + ithOccurrence);
		return find(s, pattern, ithOccurrence, 0);
	}

	private OccurrenceLocation find(StringBuffer s, String pattern, int ithOccurrence, int startIdx) {
		if (startIdx < 0 || startIdx > s.length())
			throw new IllegalStateException("startIdx = " + startIdx);
		int idx= s.indexOf(pattern, startIdx);
		if (idx == -1)
			throw new IllegalStateException("not found \"" + pattern + "\" in \"" + s.substring(startIdx));
		if (ithOccurrence == 1)
			return new OccurrenceLocation(idx, pattern.length(), 0, "");
		return find(s, pattern, ithOccurrence - 1, idx + 1);
	}

	public void testMarkMethodExits1() throws Exception {
		fFinder= new MethodExitsFinder();
		StringBuffer s= new StringBuffer();
		s.append("class A{\n");
		s.append("   int foo(String s) throws Exception {\n");
		s.append("      try {\n");
		s.append("         if (s == null)\n");
		s.append("            throw new NullPointerException();\n");
		s.append("         else if (s.length() > 10)\n");
		s.append("            throw new IllegalArgumentException();\n");
		s.append("         else\n");
		s.append("            throw new Exception();\n");
		s.append("      } catch (NullPointerException e) {\n");
		s.append("         e.printStackTrace();\n");
		s.append("      } catch (IllegalArgumentException e) {\n");
		s.append("         e.printStackTrace();\n");
		s.append("      }\n");
		s.append("      return s.length();\n");
		s.append("   }\n");
		s.append("}\n");
		int offset= 1 + s.indexOf("int");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "int", 1), find(s, "throw", 4), find(s, "return s.length();", 1) };
		checkSelection(s, offset, length, ranges);
	}

	public void testMarkMethodExits2() throws Exception {
		fFinder= new MethodExitsFinder();
		StringBuffer s= new StringBuffer();
		s.append("class A{\n");
		s.append("   int foo(String s) throws Exception {\n");
		s.append("      try {\n");
		s.append("         if (s == null)\n");
		s.append("            throw new NullPointerException();\n");
		s.append("         else if (s.length() > 10)\n");
		s.append("            throw new IllegalArgumentException();\n");
		s.append("         else\n");
		s.append("            throw new Exception();\n");
		s.append("      } catch (NullPointerException | IllegalArgumentException e) {\n");
		s.append("         e.printStackTrace();\n");
		s.append("      }\n");
		s.append("      return s.length();\n");
		s.append("   }\n");
		s.append("}\n");
		int offset= 1 + s.indexOf("int");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "int", 1), find(s, "throw", 4), find(s, "return s.length();", 1) };
		checkSelection(s, offset, length, ranges);
	}

	public void testMarkMethodExits3() throws Exception {
		fFinder= new MethodExitsFinder();
		StringBuffer s= new StringBuffer();
		s.append("import java.io.BufferedReader;\n");
		s.append("import java.io.FileReader;\n");
		s.append("import java.io.LineNumberReader;\n");
		s.append("class A {\n");
		s.append("   void foo() throws Throwable {\n");
		s.append("      try (LineNumberReader reader = new LineNumberReader(new BufferedReader(\n");
		s.append("            new FileReader(\"somefile\")))) {\n");
		s.append("         String line;\n");
		s.append("         while ((line = reader.readLine()) != null) {\n");
		s.append("            System.out.println(line);\n");
		s.append("         }\n");
		s.append("      }\n");
		s.append("   }\n");
		s.append("}\n");

		int offset= 1 + s.indexOf("void");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "void", 1), find(s, "reader", 1), find(s, "FileReader", 2), find(s, "readLine", 1), find(s, "}", 2), find(s, "}", 3) };
		checkSelection(s, offset, length, ranges);
	}

	public void testMarkMethodExits4() throws Exception {
		fFinder= new MethodExitsFinder();
		StringBuffer s= new StringBuffer();
		s.append("import java.io.BufferedReader;\n");
		s.append("import java.io.FileNotFoundException;\n");
		s.append("import java.io.FileReader;\n");
		s.append("import java.io.LineNumberReader;\n");
		s.append("class A {\n");
		s.append("   void foo() throws Throwable {\n");
		s.append("      try (LineNumberReader reader = new LineNumberReader(new BufferedReader(\n");
		s.append("            new FileReader(\"somefile\")))) {\n");
		s.append("         String line;\n");
		s.append("         while ((line = reader.readLine()) != null) {\n");
		s.append("            System.out.println(line);\n");
		s.append("         }\n");
		s.append("      } catch (FileNotFoundException e) {\n");
		s.append("         e.printStackTrace();\n");
		s.append("      }\n");
		s.append("   }\n");
		s.append("}\n");

		int offset= 1 + s.indexOf("void");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "void", 1), find(s, "reader", 1), find(s, "readLine", 1), find(s, "}", 2), find(s, "}", 4) };
		checkSelection(s, offset, length, ranges);
	}

	public void testMarkMethodExits5() throws Exception {
		fFinder= new MethodExitsFinder();
		StringBuffer s= new StringBuffer();
		s.append("import java.io.BufferedReader;\n");
		s.append("import java.io.FileReader;\n");
		s.append("import java.io.IOException;\n");
		s.append("import java.io.LineNumberReader;\n");
		s.append("class A {\n");
		s.append("   void foo() throws Throwable {\n");
		s.append("      try (LineNumberReader reader = new LineNumberReader(new BufferedReader(\n");
		s.append("            new FileReader(\"somefile\")))) {\n");
		s.append("         String line;\n");
		s.append("         while ((line = reader.readLine()) != null) {\n");
		s.append("            System.out.println(line);\n");
		s.append("         }\n");
		s.append("      } catch (IOException e) {\n");
		s.append("         e.printStackTrace();\n");
		s.append("      }\n");
		s.append("   }\n");
		s.append("}\n");

		int offset= 1 + s.indexOf("void");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "void", 1), find(s, "}", 4) };
		checkSelection(s, offset, length, ranges);
	}

	public void testMarkMethodExits6() throws Exception {
		fFinder= new MethodExitsFinder();
		StringBuffer s= new StringBuffer();
		s.append("import java.io.FileReader;\n");
		s.append("class A {\n");
		s.append("   void foo() throws Throwable {\n");
		s.append("      try (FileReader reader1 = new FileReader(\"file1\");\n");
		s.append("      FileReader reader2 = new FileReader(\"file2\");\n");
		s.append("      FileReader reader3 = new FileReader(\"file3\")) {\n");
		s.append("         int ch;\n");
		s.append("         while ((ch = reader1.read()) != -1) {\n");
		s.append("            System.out.println(ch);\n");
		s.append("         }\n");
		s.append("      }\n");
		s.append("   }\n");
		s.append("}\n");

		int offset= 1 + s.indexOf("void");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "void", 1),
				find(s, "reader1", 1), find(s, "FileReader", 3),
				find(s, "reader2", 1), find(s, "FileReader", 5),
				find(s, "reader3", 1), find(s, "FileReader", 7),
				find(s, "read", 5), find(s, "}", 2), find(s, "}", 3) };
		checkSelection(s, offset, length, ranges);
	}

	public void testMarkMethodExits7() throws Exception {
		fFinder= new MethodExitsFinder();
		StringBuffer s= new StringBuffer();
		s.append("import java.io.FileReader;\n");
		s.append("class A {\n");
		s.append("   void foo() throws Throwable {\n");
		s.append("      try (ACloseable closeable = new ACloseable();\n");
		s.append("               FileReader reader = new FileReader(\"file1\")) {\n");
		s.append("         int ch;\n");
		s.append("         while ((ch = reader.read()) != -1) {\n");
		s.append("            System.out.println(ch);\n");
		s.append("         }\n");
		s.append("      }\n");
		s.append("   }\n");
		s.append("}\n");
		s.append("class ACloseable implements AutoCloseable {\n");
		s.append("    @Override\n");
		s.append("    public void close() { }\n");
		s.append("}\n");
		int offset= 1 + s.indexOf("void");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "void", 1), find(s, "reader", 1), find(s, "FileReader", 3), find(s, "read", 3), find(s, "}", 2), find(s, "}", 3) };
		checkSelection(s, offset, length, ranges);
	}
	
	public void testThrowingException1() throws Exception {
		fFinder= new ExceptionOccurrencesFinder();
		StringBuffer s= new StringBuffer();
		s.append("class A{\n");
		s.append("   int foo(String s) throws Exception {\n");
		s.append("      try {\n");
		s.append("         if (s == null)\n");
		s.append("            throw new NullPointerException();\n");
		s.append("         else if (s.length() > 10)\n");
		s.append("            throw new IllegalArgumentException();\n");
		s.append("         else\n");
		s.append("            throw new Exception();\n");
		s.append("      } catch (NullPointerException e) {\n");
		s.append("         e.printStackTrace();\n");
		s.append("      } catch (IllegalArgumentException e) {\n");
		s.append("         e.printStackTrace();\n");
		s.append("      }\n");
		s.append("      return s.length();\n");
		s.append("   }\n");
		s.append("}\n");
		int offset= 1 + s.indexOf("NullPointerException e");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "throw", 2), find(s, "NullPointerException", 2) };
		checkSelection(s, offset, length, ranges);
	}

	public void testThrowingException2() throws Exception {
		fFinder= new ExceptionOccurrencesFinder();
		StringBuffer s= new StringBuffer();
		s.append("class A{\n");
		s.append("   int foo(String s) throws Exception {\n");
		s.append("      try {\n");
		s.append("         if (s == null)\n");
		s.append("            throw new NullPointerException();\n");
		s.append("         else if (s.length() > 10)\n");
		s.append("            throw new IllegalArgumentException();\n");
		s.append("         else\n");
		s.append("            throw new Exception();\n");
		s.append("      } catch (NullPointerException | IllegalArgumentException e) {\n");
		s.append("         e.printStackTrace();\n");
		s.append("      }\n");
		s.append("      return s.length();\n");
		s.append("   }\n");
		s.append("}\n");
		int offset= 1 + s.indexOf("NullPointerException | ");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "throw", 2), find(s, "NullPointerException", 2) };
		checkSelection(s, offset, length, ranges);
	}

	public void testThrowingException3() throws Exception {
		fFinder= new ExceptionOccurrencesFinder();
		StringBuffer s= new StringBuffer();
		s.append("import java.io.BufferedReader;\n");
		s.append("import java.io.FileNotFoundException;\n");
		s.append("import java.io.FileReader;\n");
		s.append("import java.io.LineNumberReader;\n");
		s.append("class A {\n");
		s.append("   void foo() throws Throwable {\n");
		s.append("      try (LineNumberReader reader = new LineNumberReader(new BufferedReader(\n");
		s.append("            new FileReader(\"somefile\")))) {\n");
		s.append("         String line;\n");
		s.append("         while ((line = reader.readLine()) != null) {\n");
		s.append("            System.out.println(line);\n");
		s.append("         }\n");
		s.append("      } catch (FileNotFoundException e) {\n");
		s.append("         e.printStackTrace();\n");
		s.append("      }\n");
		s.append("   }\n");
		s.append("}\n");

		int offset= 1 + s.indexOf("FileNotFoundException e");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "FileNotFoundException", 2), find(s, "FileReader", 2) };
		checkSelection(s, offset, length, ranges);
	}

	public void testThrowingException4() throws Exception {
		fFinder= new ExceptionOccurrencesFinder();
		StringBuffer s= new StringBuffer();
		s.append("import java.io.BufferedReader;\n");
		s.append("import java.io.FileReader;\n");
		s.append("import java.io.IOException;\n");
		s.append("import java.io.LineNumberReader;\n");
		s.append("class A {\n");
		s.append("   void foo() throws Throwable {\n");
		s.append("      try (LineNumberReader reader = new LineNumberReader(new BufferedReader(\n");
		s.append("            new FileReader(\"somefile\")))) {\n");
		s.append("         String line;\n");
		s.append("         while ((line = reader.readLine()) != null) {\n");
		s.append("            System.out.println(line);\n");
		s.append("         }\n");
		s.append("      } catch (IOException e) {\n");
		s.append("         e.printStackTrace();\n");
		s.append("      }\n");
		s.append("   }\n");
		s.append("}\n");

		int offset= 1 + s.indexOf("IOException e");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "IOException", 2), find(s, "FileReader", 2), find(s, "readLine", 1), find(s, "}", 2), find(s, "reader", 1) };
		checkSelection(s, offset, length, ranges);
	}

	public void testThrowingException5() throws Exception {
		fFinder= new ExceptionOccurrencesFinder();
		StringBuffer s= new StringBuffer();
		s.append("import java.io.FileReader;\n");
		s.append("import java.io.IOException;\n");
		s.append("class A {\n");
		s.append("   void foo() throws Throwable {\n");
		s.append("      try (FileReader reader1 = new FileReader(\"file1\");\n");
		s.append("      FileReader reader2 = new FileReader(\"file2\");\n");
		s.append("      FileReader reader3 = new FileReader(\"file3\")) {\n");
		s.append("         int ch;\n");
		s.append("         while ((ch = reader1.read()) != -1) {\n");
		s.append("            System.out.println(ch);\n");
		s.append("         }\n");
		s.append("      } catch (IOException e) {\n");
		s.append("         e.printStackTrace();\n");
		s.append("      }\n");
		s.append("   }\n");
		s.append("}\n");

		int offset= 1 + s.indexOf("IOException e");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "IOException", 2), find(s, "FileReader", 3), find(s, "FileReader", 5), find(s, "FileReader", 7), find(s, "read", 5),
				find(s, "}", 2), find(s, "reader1", 1), find(s, "reader2", 1), find(s, "reader3", 1) };
		checkSelection(s, offset, length, ranges);
	}

	public void testThrowingException6() throws Exception {
		fFinder= new ExceptionOccurrencesFinder();
		StringBuffer s= new StringBuffer();
		s.append("import java.io.FileReader;\n");
		s.append("class A {\n");
		s.append("   void foo() throws Throwable {\n");
		s.append("      try (FileReader reader1 = new FileReader(\"file1\");\n");
		s.append("      FileReader reader2 = new FileReader(\"file2\");\n");
		s.append("      FileReader reader3 = new FileReader(\"file3\")) {\n");
		s.append("         int ch;\n");
		s.append("         while ((ch = reader1.read()) != -1) {\n");
		s.append("            System.out.println(ch);\n");
		s.append("         }\n");
		s.append("      }\n");
		s.append("   }\n");
		s.append("}\n");

		int offset= 1 + s.indexOf("Throwable");//middle of word
		int length= 0;
		OccurrenceLocation[] ranges= { find(s, "Throwable", 1),
				find(s, "reader1", 1), find(s, "FileReader", 3),
				find(s, "reader2", 1), find(s, "FileReader", 5),
				find(s, "reader3", 1), find(s, "FileReader", 7),
				find(s, "read", 5), find(s, "}", 2) };
		checkSelection(s, offset, length, ranges);
	}
}
