/*******************************************************************************
 * Copyright (c) 2016, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jdt.core.tests.model;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
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.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IModuleDescription;
import org.eclipse.jdt.core.IOrdinaryClassFile;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
import org.eclipse.jdt.internal.core.search.indexing.IndexRequest;

import junit.framework.Test;

public class ResolveTests9 extends AbstractJavaModelTests {
	private static final int MODULE = 1;
	private static final int WITHOUT_TEST = 2;
	private static final int TEST = 4;

	ICompilationUnit wc = null;

	static {
//		 TESTS_NAMES = new String[] { "testModuleInfo_" };
//		 TESTS_NUMBERS = new int[] { 124 };
//		 TESTS_RANGE = new int[] { 16, -1 };
	}
	public static Test suite() {
		return buildModelTestSuite(ResolveTests9.class);
	}
	public ResolveTests9(String name) {
		super(name);
	}
	@Override
	public ICompilationUnit getWorkingCopy(String path, String source) throws JavaModelException {
		return super.getWorkingCopy(path, source, this.wcOwner);
	}
	@Override
	public void setUpSuite() throws Exception {
		super.setUpSuite();

		IJavaProject project = setUpJavaProject("Resolve", "9", true);

		String bootModPath = System.getProperty("java.home") + File.separator +"jrt-fs.jar";
		IClasspathEntry jrtEntry = JavaCore.newLibraryEntry(new Path(bootModPath), null, null, null, null, false);
		IClasspathEntry[] old = project.getRawClasspath();
		IClasspathEntry[] newPath = new IClasspathEntry[old.length +1];
		System.arraycopy(old, 0, newPath, 0, old.length);
		newPath[old.length] = jrtEntry;
		project.setRawClasspath(newPath, null);

		waitUntilIndexesReady();
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		this.wcOwner = new WorkingCopyOwner(){};
	}
	@Override
	public void tearDownSuite() throws Exception {
		deleteProject("Resolve");

		super.tearDownSuite();
	}

	@Override
	protected void tearDown() throws Exception {
		if (this.wc != null) {
			this.wc.discardWorkingCopy();
		}
		super.tearDown();
	}

	void addProjectEntry(IJavaProject thisProject, IJavaProject otherProject, int flags) throws JavaModelException {
		addClasspathEntry(thisProject,
				JavaCore.newProjectEntry(otherProject.getPath(), null, false, attributes(flags), false));
	}
	IClasspathAttribute[] attributes(int flags) {
		List<IClasspathAttribute> attrs = new ArrayList<>();
		if ((flags & MODULE) != 0)
			attrs.add(JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"));
		if ((flags & WITHOUT_TEST) != 0)
			attrs.add(JavaCore.newClasspathAttribute(IClasspathAttribute.WITHOUT_TEST_CODE, "true"));
		if ((flags & TEST) != 0)
			attrs.add(JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true"));
		return attrs.toArray(new IClasspathAttribute[attrs.size()]);
	}
	void addTestSrc(IJavaProject prj) throws CoreException {
		IPath path = prj.getProject().getFullPath();
		IClasspathEntry testSrc = JavaCore.newSourceEntry(path.append(new Path("src-test")),
				null, null, path.append(new Path("bin-test")),
				new IClasspathAttribute[] {JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true")});
		addClasspathEntry(prj, testSrc);
		createFolder(prj.getElementName() + "/src-test");
	}

	public void testModuleInfo_serviceImplementation_OK() throws CoreException {
		IFile modInfo = null;
		try {
			getWorkingCopy(
					"/Resolve/src/test/ITest.java",
					"public interface ITest {}\n");
			getWorkingCopy(
					"/Resolve/src/test/TestClass.java",
					"public class TestClass implements ITest {}\n");

			this.wc = getWorkingCopy(
					"/Resolve/src/module-info.java",
					"module com.test {\n" +
					"  provides p1.Y with ResolveInterface;\n" +
					"}\n");

			String str = this.wc.getSource();
			String selection = "ResolveInterface";
			int start = str.indexOf(selection);
			int length = selection.length();

			IJavaElement[] elements = this.wc.codeSelect(start, length);
			assertElementsEqual(
				"Unexpected elements",
				"ResolveInterface [in ResolveInterface.java [in <default> [in src [in Resolve]]]]",
				elements
			);
		} finally {
			if (modInfo != null)
				deleteResource(modInfo);
		}
	}
	public void testModuleInfo_serviceInterface_OK() throws CoreException {
		IFile modInfo = null;
		IFolder testFolder = null;
		try {
			testFolder = createFolder("/Resolve/src/test");
			createFile(
					"/Resolve/src/test/ITest.java",
					"package test;\n" +
					"public interface ITest {}\n");
			createFile(
					"/Resolve/src/test/TestClass.java",
					"package test;\n" +
					"public class TestClass implements ITest {}\n");

			this.wc = getWorkingCopy(
					"/Resolve/src/module-info.java",
					"module com.test {\n" +
					"  provides test.ITest with test.TestClass;\n" +
					"}\n");

			String str = this.wc.getSource();
			String selection = "ITest";
			int start = str.indexOf(selection);
			int length = selection.length();

			IJavaElement[] elements = this.wc.codeSelect(start, length);
			assertElementsEqual(
				"Unexpected elements",
				"ITest [in ITest.java [in test [in src [in Resolve]]]]",
				elements
			);
		} finally {
			if (modInfo != null)
				deleteResource(modInfo);
			if (testFolder != null)
				deleteResource(testFolder);
		}
	}
	public void testModuleInfo_serviceInterface_almost_OK() throws CoreException {
		IFile modInfo = null;
		IFolder testFolder = null;
		IndexManager indexManager = JavaModelManager.getIndexManager();
		try {
			// block the index manager to ensure it's not ready when code select is performed:
			indexManager.request(new IndexRequest(new Path("blocker"), indexManager) {
				@Override
				public boolean execute(IProgressMonitor progress) {
					try {
						while (!this.isCancelled)
							Thread.sleep(1000);
					} catch (InterruptedException e) { /* ignore */ }
					return false;
				}
			});
			testFolder = createFolder("/Resolve/src/test");
			createFile(
					"/Resolve/src/test/ITest.java",
					"public interface ITest {}\n"); // missing package declaration
			createFile(
					"/Resolve/src/test/TestClass.java",
					"public class TestClass implements ITest {}\n");

			this.wc = getWorkingCopy(
					"/Resolve/src/module-info.java",
					"module com.test {\n" +
					"  provides test.ITest with test.TestClass;\n" +
					"}\n");

			String str = this.wc.getSource();
			String selection = "ITest";
			int start = str.indexOf(selection);
			int length = selection.length();

			// still, if we get here before indexes are ready,
			// then OperationCanceledException will send us into SearchableEnvironment.findTypes(String, ISearchRequestor, int),
			// which succeeds:
			IJavaElement[] elements = this.wc.codeSelect(start, length);
			assertElementsEqual(
				"Unexpected elements",
				"ITest [in ITest.java [in test [in src [in Resolve]]]]",
				elements
			);
		} finally {
			if (modInfo != null)
				deleteResource(modInfo);
			if (testFolder != null)
				deleteResource(testFolder);
			indexManager.discardJobs("blocker");
		}
	}
	public void testModuleInfo_serviceInterface_NOK() throws CoreException {
		IFile modInfo = null;
		IFolder testFolder = null;
		try {
			testFolder = createFolder("/Resolve/src/test");
			createFile(
					"/Resolve/src/test/ITest.java",
					"public interface ITest {}\n"); // missing package declaration
			createFile(
					"/Resolve/src/test/TestClass.java",
					"public class TestClass implements ITest {}\n");

			this.wc = getWorkingCopy(
					"/Resolve/src/module-info.java",
					"module com.test {\n" +
					"  provides test.ITest with test.TestClass;\n" +
					"}\n");

			String str = this.wc.getSource();
			String selection = "ITest";
			int start = str.indexOf(selection);
			int length = selection.length();

			waitUntilIndexesReady();
			// even after indexes are built we meanwhile (after bug 540541) find the selected type
			IJavaElement[] elements = this.wc.codeSelect(start, length);
			assertElementsEqual(
				"Unexpected elements",
				"ITest [in ITest.java [in test [in src [in Resolve]]]]",
				elements
			);
		} finally {
			if (modInfo != null)
				deleteResource(modInfo);
			if (testFolder != null)
				deleteResource(testFolder);
		}
	}
	public void testModuleInfo_noReferenceAtKeyword() throws CoreException {
		IFile providesFile = createFile("/Resolve/src/provides.java", "public class provides {}");
		IFile modInfo = null;
		try {
			getWorkingCopy(
					"/Resolve/src/test/ITest.java",
					"public interface ITest {}\n");
			getWorkingCopy(
					"/Resolve/src/test/TestClass.java",
					"public class TestClass implements ITest {}\n");

			this.wc = getWorkingCopy(
					"/Resolve/src/module-info.java",
					"module com.test {\n" +
					"  provides p1.Y with ResolveInterface;\n" +
					"}\n");

			String str = this.wc.getSource();
			String selection = "provides";
			int start = str.indexOf(selection);
			int length = selection.length();

			IJavaElement[] elements = this.wc.codeSelect(start, length);
			assertElementsEqual(
				"Unexpected elements",
				"",
				elements
			);
		} finally {
			deleteResource(providesFile);
			if (modInfo != null)
				deleteResource(modInfo);
		}
	}
	public void testModuleInfo_referenceAtKeywordInNonKWPosition() throws CoreException {
		IFile providesFile = createFile("/Resolve/src/provides.java", "public class provides implements p1.Y {}");
		IFile modInfo = null;
		try {
			getWorkingCopy(
					"/Resolve/src/test/ITest.java",
					"public interface ITest {}\n");
			getWorkingCopy(
					"/Resolve/src/test/TestClass.java",
					"public class TestClass implements ITest {}\n");

			this.wc = getWorkingCopy(
					"/Resolve/src/module-info.java",
					"module com.test {\n" +
					"  provides p1.Y with provides;\n" +
					"}\n");

			String str = this.wc.getSource();
			String selection = "provides";
			int start = str.lastIndexOf(selection);
			int length = selection.length();

			IJavaElement[] elements = this.wc.codeSelect(start, length);
			assertElementsEqual(
				"Unexpected elements",
				"provides [in provides.java [in <default> [in src [in Resolve]]]]",
				elements
			);
		} finally {
			deleteResource(providesFile);
			if (modInfo != null)
				deleteResource(modInfo);
		}
	}

	public void testClassFileInModule1() throws CoreException, IOException {
		if (!isJRE9) {
			System.err.println("Test "+getName()+" requires a JRE 9");
			return;
		}
		IJavaProject javaProject = createJava9Project("Test");
		try {
			IType type = javaProject.findType("java.util.zip.ZipFile");
			IOrdinaryClassFile classFile = type.getClassFile();
			String contents = classFile.getBuffer().getContents();
			int start = contents.indexOf("this(");
			IJavaElement[] selected = classFile.codeSelect(start, 4);
			assertElementsEqual(
					"Unexpected elements",
					"ZipFile(java.io.File, int) [in ZipFile [in ZipFile.class [in java.util.zip [in <module:java.base>]]]]",
					selected);
		} finally {
			deleteProject(javaProject);
		}
	}

	public void testUnnamedNamedConflict() throws CoreException, IOException {
		if (!isJRE9) {
			System.err.println("Test "+getName()+" requires a JRE 9");
			return;
		}
		IJavaProject mod = null;
		IJavaProject test = null;
		try {
			mod = createJava9Project("mod");
			createFolder("mod/src/p1/p2");
			createFile("mod/src/p1/p2/C.java", "package p1.p2;\n public class C {}\n");
			createFile("mod/src/module-info.java",
					"module mod {\n" +
					"	exports p1.p2;\n" +
					"}\n");
			mod.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);

			test = createJava9Project("Test");
			IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
			addClasspathEntry(test, JavaCore.newProjectEntry(new Path("/mod"), null, false, attributes, false));
			createFolder("Test/src/p1/p2");
			createFile("Test/src/p1/p2/C1.java", "package p1.p2;\n public class C1 {}\n");
			String source =
					"package q;\n" +
					"public class Main {\n" +
					"	p1.p2.C c;\n" +
					"	p1.p2.C1 c1;\n" +
					"}\n";
			createFolder("Test/src/q");
			createFile("Test/src/q/Main.java", source);
			test.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = test.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",
					"The package p1.p2 conflicts with a package accessible from another module: mod\n" +
					"The package p1.p2 is accessible from more than one module: <unnamed>, mod\n" +
					"The package p1.p2 is accessible from more than one module: <unnamed>, mod",
					markers);

			ICompilationUnit unit = getCompilationUnit("Test/src/q/Main.java");

			// test that we can select both types despite the package conflict:
			int start = source.indexOf("C c");
			IJavaElement[] selected = unit.codeSelect(start, 2);
			assertElementsEqual(
					"Unexpected elements",
					"C [in C.java [in p1.p2 [in src [in mod]]]]",
					selected);

			start = source.indexOf("C1");
			selected = unit.codeSelect(start, 2);
			assertElementsEqual(
					"Unexpected elements",
					"C1 [in C1.java [in p1.p2 [in src [in Test]]]]",
					selected);
		} finally {
			deleteProject(test);
			deleteProject(mod);
		}
	}

	public void testBug537934() throws Exception {
		if (!isJRE9) {
			System.err.println("Test "+getName()+" requires a JRE 9");
			return;
		}
		IJavaProject gui = null;
		IJavaProject model = null;
		IJavaProject type = null;
		IJavaProject logg = null;
		try {
			// ---- module log:
			//      - has log4j on the module path
			logg = createJava9ProjectWithJREAttributes("com.igorion.log", new String[] {"src"}, attributes(MODULE));
			String jarAbsPath = logg.getProject().getLocation()+"/log4j.jar";
			createJar(new String[] {
					"log4j/Dummy.java",
					"package log4j;\n" +
					"public class Dummy {}\n"
				},
				jarAbsPath);
			addLibraryEntry(logg, new Path(jarAbsPath), null, null, null, null, attributes(MODULE), false);
			createFolder("com.igorion.log/src/com/igorion/log");
			createFile("com.igorion.log/src/com/igorion/log/ILog.java",
					"package com.igorion.log;\n public interface ILog {}\n");
			createFile("com.igorion.log/src/module-info.java",
					"module com.igorion.log {\n" +
					"	requires log4j;\n" +
					"	exports com.igorion.log;\n" +
					"}\n");
			logg.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = logg.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("markers in com.igorion.log",
					"Name of automatic module \'log4j\' is unstable, it is derived from the module\'s file name.",
					markers);

			// ---- module type:
			//      - has test sources
			type = createJava9Project("com.igorion.type");
			createFolder("com.igorion.type/src/com/igorion/type");
			createFile("com.igorion.type/src/com/igorion/type/IOther.java",
					"package com.igorion.type;\n public interface IOther {}\n");
			createFile("com.igorion.type/src/module-info.java",
					"module com.igorion.type {\n" +
					"	exports com.igorion.type;\n" +
					"}\n");
			addTestSrc(type);
			type.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			markers = type.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("markers in com.igorion.type", "", markers);

			// ---- module model:
			//      - has test sources
			//      - has log4j on the module path
			//      - has modules log & type on the module path without_test_code
			model = createJava9ProjectWithJREAttributes("com.igorion.model", new String[] {"src"}, attributes(MODULE));
			createFolder("com.igorion.model/src/com/igorion/model/define");
			createFile("com.igorion.model/src/com/igorion/model/IModel.java",
					"package com.igorion.model;\n public interface IModel {}\n");
			createFile("com.igorion.model/src/com/igorion/model/define/Model.java",
					"package com.igorion.model.define;\n" +
					"import com.igorion.model.IModel;\n" +
					"import java.util.Optional;\n" +
					"public class Model {\n" +
					"	public static synchronized Optional<IModel> instance() { return Optional.empty(); }\n" +
					"}\n");
			createFile("com.igorion.model/src/module-info.java",
					"module com.igorion.model {\n" +
					"	requires com.igorion.log;\n" +
					"	exports com.igorion.model;\n" +
					"	exports com.igorion.model.define;\n" +
					"}\n");
			addTestSrc(model);
			addLibraryEntry(model, new Path(jarAbsPath), null, null, null, null, attributes(MODULE), false);
			addProjectEntry(model, logg, MODULE|WITHOUT_TEST);
			addProjectEntry(model, type, MODULE|WITHOUT_TEST);
			model.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			markers = model.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("markers in com.igorion.model", "", markers);

			// ---- module gui:
			//      - has log4j on the module path for test code
			//      - has modules type, model, log on the module path without_test_code (order is significant)
			gui = createJava9ProjectWithJREAttributes("com.igorion.gui", new String[] {"src"}, attributes(MODULE));
			addTestSrc(gui);
			createFolder("com.igorion.gui/src/com/igorion/gui");
			String source =
					"package com.igorion.gui;\n" +
					"import com.igorion.model.IModel;\n" +
					"import com.igorion.model.define.Model;\n" +
					"import java.util.Optional;\n" +
					"public class Reproduce {\n" +
					"	static void meth() {\n" +
					"		Optional<IModel> oModel = Model.instance();\n" +
					"		if (oModel.isPresent())\n" +
					"			oModel.get();\n" +
					"	}\n" +
					"}\n";
			createFile("com.igorion.gui/src/com/igorion/gui/Reproduce.java", source);
			createFile("com.igorion.gui/src/module-info.java",
					"module com.igorion.gui {\n" +
					"	requires com.igorion.type;\n" +
					"	requires com.igorion.model;\n" +
					"}\n");
			addLibraryEntry(gui, new Path(jarAbsPath), null, null, null, null, attributes(MODULE|TEST), false);
			addProjectEntry(gui, type, MODULE|WITHOUT_TEST);
			addProjectEntry(gui, model, MODULE|WITHOUT_TEST);
			addProjectEntry(gui, logg, MODULE|WITHOUT_TEST);
			gui.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			markers = gui.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("markers in com.igorion.gui", "", markers);

			// test that selection finds a fully resolved type Optional<IModel>:
			ICompilationUnit unit = getCompilationUnit("com.igorion.gui/src/com/igorion/gui/Reproduce.java");
			int start = source.indexOf("get(");
			IJavaElement[] selected = unit.codeSelect(start, 3);
			assertElementsEqual(
					"Unexpected elements",
					"get() [in Optional [in Optional.class [in java.util [in <module:java.base>]]]]",
					selected);
		} finally {
			deleteProject(gui);
			deleteProject(model);
			deleteProject(type);
			deleteProject(logg);
		}
	}
	public void testModuleCaching() throws Exception {
		if (!isJRE9 || isJRE11) {
			System.err.println("Test "+getName()+" requires a JRE [9,11)");
			return;
		}
		IJavaProject prj = createJava9Project("caching");
		try {
			IFile file = createFile("caching/src/module-info.java",
					"module caching {\n" +
					"	requires java.xml.bind;\n" +
					"}\n");
			createFolder("caching/src/p");
			createFile("caching/src/p/X.java",
					"package p;\n" +
					"@javax.xml.bind.annotation.XmlRootElement\n" +
					"public class X {}\n");
			prj.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = prj.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("unexpected markers",
					"The module java.xml.bind has been deprecated since version 9 and marked for removal",  markers);

			IModuleDescription module = prj.getModuleDescription();
			assertTrue("module exists", module.exists());
			assertEquals("module name", "caching", module.getElementName());

			// move module-info away ...
			createFolder("caching/away");
			file.move(new Path("/caching/away/module-info.java"), false, null);
			IModuleDescription mod2 = prj.getModuleDescription();
			assertNull("no longer a module", mod2);

			// ... and observe javax.xml.bind unobservable:
			prj.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			markers = prj.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("unexpected markers",
					"javax.xml.bind cannot be resolved to a type", markers);
		} finally {
			deleteProject(prj);
		}
	}
}
