/*******************************************************************************
 * 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.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);
	}
	public ICompilationUnit getWorkingCopy(String path, String source) throws JavaModelException {
		return super.getWorkingCopy(path, source, this.wcOwner);
	}
	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();
	}
	
	protected void setUp() throws Exception {
		super.setUp();
		this.wcOwner = new WorkingCopyOwner(){};
	}
	public void tearDownSuite() throws Exception {
		deleteProject("Resolve");
	
		super.tearDownSuite();
	}
	
	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",
					"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);
		}
	}
}
