/*******************************************************************************
 * Copyright (c) 2015, 2016 Google, Inc 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:
 *   Stefan Xenos (Google) - Initial implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.nd.indexer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Semaphore;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IOrdinaryClassFile;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IParent;
import org.eclipse.jdt.core.tests.model.AbstractJavaModelTests;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.core.nd.IReader;
import org.eclipse.jdt.internal.core.nd.db.ChunkCache;
import org.eclipse.jdt.internal.core.nd.db.Database;
import org.eclipse.jdt.internal.core.nd.indexer.IndexTester;
import org.eclipse.jdt.internal.core.nd.indexer.Indexer;
import org.eclipse.jdt.internal.core.nd.java.JavaIndex;
import org.eclipse.jdt.internal.core.nd.java.NdType;
import org.eclipse.jdt.internal.core.nd.java.NdTypeId;
import org.eclipse.jdt.internal.core.nd.java.model.BinaryTypeDescriptor;
import org.eclipse.jdt.internal.core.nd.java.model.BinaryTypeFactory;
import org.eclipse.jdt.internal.core.nd.java.model.IndexBinaryType;

import junit.framework.Test;

/**
 * Tests for the {@link Database} class.
 */
public class IndexerTest extends AbstractJavaModelTests {

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

	private static final String PROJECT_NAME = "IndexerTest";
	private static JavaIndex index;

	@Override
	protected void setUp() throws Exception {
		String testName = getName();
		index = JavaIndexTestUtil.createTempIndex(testName);
		super.setUp();
	}

	@Override
	protected void tearDown() throws Exception {
		deleteProject(PROJECT_NAME);
		index.getNd().getPath().delete();
		index = null;
		super.tearDown();
	}

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

	/**
	 * Verifies that if the index fails a read due to call to {@link Thread#interrupt()}, subsequent reads will
	 * still succeed.
	 */
	public void testInterruptedException() throws Exception {
		createJavaProject(PROJECT_NAME, new String[] {"src"}, new String[] {"JCL18_FULL"}, "bin", "1.8", true);
		// Create an indexfa
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		Indexer indexer = new Indexer(index.getNd(), root);
		indexer.rescan(SubMonitor.convert(null));
		// Ensure we're starting with an empty page cache by creating a new
		// Index accessor object on the same database
		JavaIndex testIndex = JavaIndex
				.getIndex(JavaIndex.createNd(index.getNd().getDB().getLocation(), new ChunkCache()));

		Semaphore semaphore = new Semaphore(0);

		boolean[] wasInterrupted = new boolean[1];
		Thread newThread = new Thread(() -> {
			try (IReader reader = testIndex.getNd().acquireReadLock()) {
				Thread.currentThread().interrupt();
				testIndex.findType("Ljava/util/List;".toCharArray());
			} catch (OperationCanceledException e) {
				wasInterrupted[0] = true;
			} finally {
				semaphore.release();
			}
		});

		newThread.start();

		semaphore.acquire();

		assertTrue(wasInterrupted[0]);
		try (IReader reader = testIndex.getNd().acquireReadLock()) {
			NdTypeId type = testIndex.findType("Ljava/util/List;".toCharArray());
			assertNotNull(type);
		}
	}

	public void testSubclassesOfGenericTypeCanBeFound() throws Exception {
		createJavaProject(PROJECT_NAME, new String[] {"src"}, new String[] {"JCL18_FULL"}, "bin", "1.8", true);
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		Indexer indexer = new Indexer(index.getNd(), root);

		indexer.rescan(SubMonitor.convert(null));

		try (IReader reader = IndexerTest.index.getNd().acquireReadLock()) {
			NdTypeId javaUtilList = IndexerTest.index.findType("Ljava/util/List;".toCharArray());
			NdTypeId javaUtilArrayList = IndexerTest.index.findType("Ljava/util/ArrayList;".toCharArray());

			boolean found = false;
			List<NdType> subtypes = javaUtilList.getSubTypes();
			for (NdType next : subtypes) {
				if (Objects.equals(next.getTypeId(), javaUtilArrayList)) {
					found = true;
				}
			}

			assertTrue("ArrayList was found as a subtype of List", found);
		}
	}

	private void collectAllClassFiles(List<? super IClassFile> result, IParent nextRoot) throws CoreException {
		for (IJavaElement child : nextRoot.getChildren()) {
			int type = child.getElementType();

			if (type == IJavaElement.CLASS_FILE) {
				result.add((IClassFile) child);
			} else if (child instanceof IParent) {
				IParent parent = (IParent) child;

				collectAllClassFiles(result, parent);
			}
		}
	}

	public void testReadingAllClassesInIndexAreEquivalentToOriginalJarFiles() throws Exception {
		IJavaProject javaProject = createJavaProject(PROJECT_NAME, new String[] {"src"}, new String[] {"JCL18_FULL"}, "bin", "1.8", true);
		addClassFolder(javaProject, "lib", new String[] {
				"p/Outer.java",
				"import java.lang.annotation.*;\n" +
				"\n" +
				"@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE_USE) @interface A0 {}\n" +
				"@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE_USE) @interface A {}\n" +
				"@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @interface M {}\n" +
				"@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) @interface P {}\n" +
				"\n" +
				"class Outer {\n" +
				"    class Middle1 {\n" +
				"        class Inner {}\n" +
				"    }\n" +
				"    static class Middle2 {\n" +
				"        class Inner {}\n" +
				"        static class Middle3 {\n" +
				"            class Inner2{};\n" +
				"        }\n" +
				"    }\n" +
				"    Middle1.@A Inner e1;\n" +
				"    Middle2.@A Inner e2;\n" +
				"    Middle2.Middle3.@A Inner2 e3;\n" +
				"    @M void foo(@A0 Object p0, @P Middle2.Middle3.@A Inner2 e3) {};\n" +
				"    class Middle4 extends @A Middle1 {}\n" +
				"}\n",
			}, "1.8");

		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		Indexer indexer = new Indexer(index.getNd(), root);

		indexer.rescan(SubMonitor.convert(null));

		boolean foundAtLeastOneClass = false;
		SubMonitor subMonitor = SubMonitor.convert(null);
		JavaIndex localIndex = IndexerTest.index;
		try (IReader reader = localIndex.getNd().acquireReadLock()) {
			IPackageFragmentRoot[] roots = javaProject.getAllPackageFragmentRoots();
			subMonitor.setWorkRemaining(roots.length);
			for (IPackageFragmentRoot next : roots) {
				SubMonitor iterationMon = subMonitor.split(1);
				if (next.getKind() == IPackageFragmentRoot.K_BINARY) {
					List<IClassFile> result = new ArrayList<>();
					collectAllClassFiles(result, next);
					iterationMon.setWorkRemaining(result.size());
					for (IClassFile nextClass : result) {
						if (!(nextClass instanceof IOrdinaryClassFile)) continue;
						SubMonitor classMon = iterationMon.split(1);
						BinaryTypeDescriptor descriptor = BinaryTypeFactory.createDescriptor((IOrdinaryClassFile) nextClass);
						IndexBinaryType indexedBinaryType = (IndexBinaryType)BinaryTypeFactory.readFromIndex(localIndex, descriptor, classMon);
						ClassFileReader originalBinaryType = BinaryTypeFactory.rawReadType(descriptor, true);

						if (!indexedBinaryType.exists()) {
							throw new IllegalStateException("Unable to find class in index " + new String(descriptor.indexPath));
						}
						IndexTester.testType(originalBinaryType, indexedBinaryType);
						foundAtLeastOneClass = true;
					}
				}
			}
		}
		assertTrue("No classes found in the index", foundAtLeastOneClass);
	}

	public void testFindTypesBySimpleName() throws CoreException {
		createJavaProject(PROJECT_NAME, new String[] {"src"}, new String[] {"JCL18_FULL"}, "bin", "1.8", true);
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		Indexer indexer = new Indexer(index.getNd(), root);

		indexer.rescan(SubMonitor.convert(null));

		try (IReader reader = IndexerTest.index.getNd().acquireReadLock()) {
			List<Object> javaUtilList = IndexerTest.index.findTypesBySimpleName("ArrayList".toCharArray()).stream()
					.map(new Function<NdTypeId, String>() {
						@Override
						public String apply(NdTypeId typeId) {
							return typeId.toString();
						}
					}).collect(Collectors.toList());
			System.out.println(javaUtilList);
			assertTrue("Test failed", javaUtilList.contains("Ljava/util/ArrayList;"));
		}
	}

	public void testFindTypesBySimpleNameFirstWord() throws CoreException {
		createJavaProject(PROJECT_NAME, new String[] {"src"}, new String[] {"JCL18_FULL"}, "bin", "1.8", true);
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		Indexer indexer = new Indexer(index.getNd(), root);

		indexer.rescan(SubMonitor.convert(null));

		try (IReader reader = IndexerTest.index.getNd().acquireReadLock()) {
			List<Object> javaUtilList = IndexerTest.index.findTypesBySimpleName("Array".toCharArray()).stream()
					.map(new Function<NdTypeId, String>() {
						@Override
						public String apply(NdTypeId typeId) {
							return typeId.toString();
						}
					}).collect(Collectors.toList());
			System.out.println(javaUtilList);
			assertTrue("Test failed",
					javaUtilList.containsAll(Arrays.asList("Ljava/sql/Array;", "Ljava/lang/reflect/Array;",
							"Ljava/util/concurrent/ArrayBlockingQueue;", "Ljava/util/ArrayDeque;",
							"Ljava/lang/ArrayIndexOutOfBoundsException;", "Ljava/util/ArrayList;",
							"Ljava/util/ArrayPrefixHelpers;", "Ljava/util/Arrays;",
							"Ljava/util/ArraysParallelSortHelpers;", "Ljava/lang/ArrayStoreException;")));
		}
	}

	public void testFindTypesBySimpleNameFirstLetterCount10() throws CoreException {
		createJavaProject(PROJECT_NAME, new String[] {"src"}, new String[] {"JCL18_FULL"}, "bin", "1.8", true);
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		Indexer indexer = new Indexer(index.getNd(), root);

		indexer.rescan(SubMonitor.convert(null));

		try (IReader reader = IndexerTest.index.getNd().acquireReadLock()) {
			List<Object> javaUtilList = IndexerTest.index.findTypesBySimpleName("A".toCharArray(), 10).stream()
					.map(new Function<NdTypeId, String>() {
						@Override
						public String apply(NdTypeId typeId) {
							return typeId.toString();
						}
					}).collect(Collectors.toList());
			System.out.println(javaUtilList);
			assertTrue("Test failed", javaUtilList.size() == 10);
		}
	}
}
