/*******************************************************************************
 * Copyright (c) 2000, 2018 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
 *     Terry Parker <tparker@google.com> - Enable the Java model caches to recover from IO errors - https://bugs.eclipse.org/455042
 *******************************************************************************/
package org.eclipse.jdt.core.tests.model;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;

import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.core.ClasspathEntry;
import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.core.NameLookup;

import junit.framework.Test;

/**
 * These test ensure that modifications in Java projects are correctly reported as
 * IJavaEllementDeltas.
 */
public class NameLookupTests2 extends ModifyingResourceTests {

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

	// Use this static initializer to specify subset for tests
	// All specified tests which do not belong to the class are skipped...
	static {
//		org.eclipse.jdt.internal.core.search.matching.MatchLocator.PRINT_BUFFER = false;
//		TESTS_PREFIX =  "testArray";
//		TESTS_NAMES = new String[] { "testFindBinaryTypeWithDollarName" };
//		TESTS_NUMBERS = new int[] { 8 };
//		TESTS_RANGE = new int[] { 6, -1 };
	}

public static Test suite() {
	return buildModelTestSuite(NameLookupTests2.class);
}

NameLookup getNameLookup(JavaProject project) throws JavaModelException {
	return project.newNameLookup((WorkingCopyOwner)null);
}
public void testAddPackageFragmentRootAndPackageFrament() throws CoreException {
	try {
		IJavaProject p1 = createJavaProject("P1", new String[] {"src1"}, "bin");
		IJavaProject p2 = createJavaProject("P2", new String[] {}, "");
		IClasspathEntry[] classpath =
			new IClasspathEntry[] {
				JavaCore.newProjectEntry(new Path("/P1"))
			};
		p2.setRawClasspath(classpath, null);

		IPackageFragment[] res = getNameLookup((JavaProject)p2).findPackageFragments("p1", false);
		assertTrue("Should get no package fragment", res == null);

		IClasspathEntry[] classpath2 =
			new IClasspathEntry[] {
				JavaCore.newSourceEntry(new Path("/P1/src1")),
				JavaCore.newSourceEntry(new Path("/P1/src2"))
			};
		p1.setRawClasspath(classpath2, null);
		createFolder("/P1/src2/p1");

		res = getNameLookup((JavaProject)p2).findPackageFragments("p1", false);
		assertTrue(
			"Should get 'p1' package fragment",
			res != null &&
			res.length == 1 &&
			res[0].getElementName().equals("p1"));

	} finally {
		deleteProject("P1");
		deleteProject("P2");
	}
}
public void testAddPackageFragment() throws CoreException {
	try {
		createJavaProject("P1", new String[] {"src1"}, "bin");
		IJavaProject p2 = createJavaProject("P2", new String[] {}, "");
		IClasspathEntry[] classpath =
			new IClasspathEntry[] {
				JavaCore.newProjectEntry(new Path("/P1"))
			};
		p2.setRawClasspath(classpath, null);

		IPackageFragment[] res = getNameLookup((JavaProject)p2).findPackageFragments("p1", false);
		assertTrue("Should get no package fragment", res == null);

		createFolder("/P1/src1/p1");

		res = getNameLookup((JavaProject)p2).findPackageFragments("p1", false);
		assertTrue(
			"Should get 'p1' package fragment",
			res != null &&
			res.length == 1 &&
			res[0].getElementName().equals("p1"));

	} finally {
		deleteProject("P1");
		deleteProject("P2");
	}
}
/*
 * Resolve, add pkg, resolve again: new pkg should be accessible
 * (regression test for bug 37962 Unexpected transient problem during reconcile
 */
public void testAddPackageFragment2() throws CoreException {
	try {
		JavaProject project = (JavaProject)createJavaProject("P", new String[] {"src"}, "bin");
		createFolder("/P/src/p1");

		IPackageFragment[] pkgs = getNameLookup(project).findPackageFragments("p1", false);
		assertElementsEqual(
			"Didn't find p1",
			"p1 [in src [in P]]",
			pkgs);

		createFolder("/P/src/p2");

		pkgs = getNameLookup(project).findPackageFragments("p2", false);
		assertElementsEqual(
			"Didn't find p2",
			"p2 [in src [in P]]",
			pkgs);
	} finally {
		deleteProject("P");
	}
}
/*
 * Ensures that a NameLookup can be created with working copies that contain duplicate types
 * (regression test for bug 63245 findPackageFragment won't return default package)
 */
public void testDuplicateTypesInWorkingCopies() throws CoreException {
//	ICompilationUnit[] workingCopies = new ICompilationUnit[3];
	this.workingCopies = new ICompilationUnit[3];
	try {
		JavaProject project = (JavaProject)createJavaProject("P");
		this.workingCopies[0] = getWorkingCopy(
			"/P/X.java",
			"public class X {\n" +
			"}\n" +
			"class Other {\n" +
			"}"
		);
		this.workingCopies[1] = getWorkingCopy(
			"/P/Y.java",
			"public class Y {\n" +
			"}\n" +
			"class Other {\n" +
			"}"
		);
		this.workingCopies[2] = getWorkingCopy(
			"/P/Z.java",
			"public class Z {\n" +
			"}\n" +
			"class Other {\n" +
			"}"
		);
		NameLookup nameLookup = project.newNameLookup(this.workingCopies);
		IType type = nameLookup.findType("Other", false, NameLookup.ACCEPT_ALL); // TODO (jerome) should use seekTypes
		assertTypesEqual(
			"Unepexted types",
			"Other\n",
			new IType[] {type}
		);
	} finally {
//		discardWorkingCopies(workingCopies);
		deleteProject("P");
	}
}
/*
 * Find a default package fragment in a non-default root by its path.
 * (regression test for bug 63245 findPackageFragment won't return default package)
 */
public void testFindDefaultPackageFragmentInNonDefaultRoot() throws CoreException {
	try {
		JavaProject project = (JavaProject)createJavaProject("P", new String[] {"src"}, "bin");

		IPackageFragment pkg = getNameLookup(project).findPackageFragment(new Path("/P/src"));
		assertElementsEqual(
			"Didn't find default package",
			"<default> [in src [in P]]",
			new IJavaElement[] {pkg});

	} finally {
		deleteProject("P");
	}
}
/*
 * Creates a package fragment and finds it in a dependent project in a batch operation
 * (regression test for bug 144776 JavaProject.resetCaches() needs to reset dependent projects
 */
public void testNameLookupFindPackageFragmentAfterCreation() throws CoreException {
	try {
		final IJavaProject p1 = createJavaProject("P1");
		final JavaProject p2 = (JavaProject) createJavaProject("P2", new String[] {""}, new String[0], new String[] {"/P1"}, "");

		// populate namelookup for p2
		getNameLookup(p2);

		IWorkspaceRunnable runnable = new IWorkspaceRunnable(){
			public void run(IProgressMonitor monitor) throws CoreException {
				p1.getPackageFragmentRoot(p1.getProject()).createPackageFragment("pkg", false/*don't force*/, monitor);
				IPackageFragment[] pkgs = getNameLookup(p2).findPackageFragments("pkg", false/*exact match*/);
				assertElementsEqual(
					"Unexpected package fragments",
					"pkg [in <project root> [in P1]]",
					pkgs);
			}
		};
		JavaCore.run(runnable, null/*no progress*/);
	} finally {
		deleteProject("P1");
		deleteProject("P2");
	}
}
/*
 * Ensure that finding a package fragment with a working copy opened returns one element only
 * (regression test for bug 89624 Open on selection proposes twice the same entry)
 */
public void testFindPackageFragmentWithWorkingCopy() throws CoreException {
	this.workingCopies = new ICompilationUnit[1];
	try {
		JavaProject project = (JavaProject)createJavaProject("P");
		createFolder("/P/p1");
		this.workingCopies[0] = getWorkingCopy(
			"/P/p1/X.java",
			"package p1;\n" +
			"public class X {\n" +
			"}"
		);
		NameLookup nameLookup = project.newNameLookup(this.workingCopies);
		IJavaElement[] pkgs = nameLookup.findPackageFragments("p1", false/*not a partial match*/);
		assertElementsEqual(
			"Unexpected packages",
			"p1 [in <project root> [in P]]",
			pkgs);
	} finally {
		deleteProject("P");
	}
}
/*
 * Ensure that a package fragment with a path with a length equals to an external jar path length + 1
 * is not found
 * (regression test for bug 266771 NameLookup.findPackageFragment returns very incorrect package fragments)
 */
public void testFindPackageFragment2() throws CoreException {
	try {
		JavaProject project = (JavaProject)createJavaProject("P", new String[0], new String[] {"JCL_LIB"}, "bin");
		NameLookup nameLookup =getNameLookup(project);
		IPath pathToSearch = new Path(getExternalJCLPathString() + 'a');
		IPackageFragment pkg = nameLookup.findPackageFragment(pathToSearch);
		assertElementEquals(
			"Unexpected package",
			"<null>",
			pkg);
	} finally {
		deleteProject("P");
	}
}

/*
 * Ensure that a member type with a name ending with a dollar and a number is found
 * (regression test for bug 103466 Stack Overflow: Requesting Java AST from selection)
 */
public void testFindBinaryTypeWithDollarName() throws CoreException, IOException {
	try {
		IJavaProject project = createJavaProject("P");
		addLibrary(project, "lib.jar", "libsrc.zip",
			new String[] {
				"p/X.java",
				"package p;\n" +
				"public class X {\n" +
				"  public class $1 {\n" +
				"    public class $2 {\n" +
				"    }\n" +
				"  }\n" +
				"}"
			},
			"1.4");
		IType type = getNameLookup((JavaProject) project).findType("p.X$$1", false, NameLookup.ACCEPT_ALL);
		assertTypesEqual(
			"Unexpected type",
			"p.X$$1\n",
			new IType[] {type});
	} finally {
		deleteProject("P");
	}
}
/*
 * Ensure that a type with the same simple name as its member type is found
 * (regression test for bug 102286 Error when trying F4-Type Hierarchy)
 */
public void testFindBinaryTypeWithSameNameAsMember() throws CoreException, IOException {
	try {
		IJavaProject project = createJavaProject("P", new String[] {}, new String[] {"/P/lib"}, new String[] {}, "bin");
		createFolder("/P/lib/p");
		createFile("/P/lib/p/X.class", "");
		createFile("/P/lib/p/X$X.class", "");
		IType type = getNameLookup((JavaProject) project).findType("p.X", false, NameLookup.ACCEPT_ALL);
		assertTypesEqual(
			"Unexpected type",
			"p.X\n",
			new IType[] {type});
	} finally {
		deleteProject("P");
	}
}
/*
 * Ensures that a type in working copy opened in an unrelated project is not found
 * (regression test for bug 169970 [model] code assist favorites must honour build path of project in context)
 */
public void testFindTypeWithUnrelatedWorkingCopy() throws Exception {
	ICompilationUnit workingCopy = null;
	try {
		createJavaProject("P1");
		createFolder("/P1/p");
		createFile(
			"/P1/p/X.java",
			"package p;\n" +
			"public class X {\n" +
			"}"
		);
		workingCopy = getCompilationUnit("/P1/p/X.java");
		workingCopy.becomeWorkingCopy(null);
		IJavaProject p2 = createJavaProject("P2");
		NameLookup nameLookup = ((JavaProject) p2).newNameLookup(DefaultWorkingCopyOwner.PRIMARY);
		IType type = nameLookup.findType("p.X", false, NameLookup.ACCEPT_ALL);
		assertNull("Should not find p.X in P2", type);
	} finally {
		if (workingCopy != null)
			workingCopy.discardWorkingCopy();
		deleteProject("P1");
		deleteProject("P2");
	}
}
/*
 * A test for bug 162621. Tests that a library jar that is initially invalid but transitions
 * to being valid becomes visible in name lookup. Previously the jar would stay in the invalid
 * archive cache until a classpath change was generated, and would not make it into the project's
 * JavaProjectElementInfo cache without restarting Eclipse or closing and reopening the project.
 */
public void testTransitionFromInvalidToValidJar() throws CoreException, IOException {
	String transitioningJar = getExternalPath() + "transitioningJar.jar";
	java.nio.file.Path transitioningJarPath = FileSystems.getDefault().getPath(transitioningJar);
	IPath transitioningIPath = Path.fromOSString(transitioningJar);

	try {
		Util.createJar(
				new String[] {
						"test1/IResource.java", //$NON-NLS-1$
						"package test1;\n" + //$NON-NLS-1$
						"public class IResource {\n" + //$NON-NLS-1$
						"}" //$NON-NLS-1$
					},
				new String[] {
					"META-INF/MANIFEST.MF",
					"Manifest-Version: 1.0\n"
				},
				transitioningJar,
				JavaCore.VERSION_1_4);

		// Set up the project with the invalid jar and allow all of the classpath validation
		// and delta processing to complete.
		JavaModelManager.throwIoExceptionsInGetZipFile = true;
		JavaProject proj = (JavaProject) createJavaProject("P", new String[] {}, new String[] {transitioningJar}, "bin");
		JavaModelManager.getJavaModelManager().getJavaModel().refreshExternalArchives(null, null);
		waitForAutoBuild();

		assertTrue("The invalid archive cache should report that the jar is invalid",
				!JavaModelManager.getJavaModelManager().getArchiveValidity(transitioningIPath).isValid());
		IType type = getNameLookup(proj).findType("test1.IResource", false, NameLookup.ACCEPT_CLASSES);
		assertEquals("Name lookup should fail when the jar is invalid", null, type);

		// Cause IO exceptions to be thrown on all file operations
		JavaModelManager.throwIoExceptionsInGetZipFile = false;

		// Since the timestamp hasn't changed, an external archive refresh isn't going
		// to update the caches or cause name lookups to work.
		JavaModelManager.getJavaModelManager().getJavaModel().refreshExternalArchives(null, null);
		assertTrue("External archive refresh sees no changes, so the invalid archive cache should be unchanged",
				!JavaModelManager.getJavaModelManager().getArchiveValidity(transitioningIPath).isValid());
		type = getNameLookup(proj).findType("test1.IResource", false, NameLookup.ACCEPT_CLASSES);
		assertEquals("External archive refresh sees no changes, so the project cache should be unchanged",
				null, type);

		// Re-validating the jar via validateClasspathEntry() forces eviction from the
		// invalid archive cache more quickly than waiting for the time-based eviction,
		// allowing the test to run more quickly.
		IClasspathEntry transitioningEntry = JavaCore.newLibraryEntry(transitioningIPath, null, null);
		ClasspathEntry.validateClasspathEntry(proj, transitioningEntry, false, false);

		assertFalse("The invalid archive cache should no longer report the jar as invalid",
				!JavaModelManager.getJavaModelManager().getArchiveValidity(transitioningIPath).isValid());
		type = getNameLookup(proj).findType("test1.IResource", false, NameLookup.ACCEPT_CLASSES);
		assertFalse("Name lookup should be able to find types in the valid jar", type == null);
	} finally {
		Files.deleteIfExists(transitioningJarPath);
		deleteProject("P");
	}
}
}

