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

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IOrdinaryClassFile;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.nd.indexer.Indexer;

import junit.framework.Test;

public class JavaModelManagerTests extends AbstractJavaModelTests {

	private static final IProgressMonitor NULL_MONITOR = new NullProgressMonitor();
	private static final String PROJECT_NAME = JavaModelManagerTests.class.getSimpleName();

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

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

	/**
	 * Test for Bug 548456 - Concurrency problem with JavaModelManager and JavaElement.openWhenClosed()
	 *
	 * We create a project with a jar on its class path and ask after {@link JavaElement#exists()}
	 * for a class in the jar. We do so from 2 different threads in parallel; with sufficient repetitions
	 * we hope to run into the race condition described in the bug.
	 */
	public void testBug548456_concurrentElementInfoAccess() throws Exception {
		int iterations = 20;
		int numberOfThreads = 10;
		for (int i = 0; i < iterations; ++i) {
			doTestBug548456_concurrentCallBinaryTypeExists(numberOfThreads);
		}
	}

	private void doTestBug548456_concurrentCallBinaryTypeExists(int numberOfThreads) throws Exception {
		final IJavaProject project = setUpJavaProject(PROJECT_NAME);
		try {
			buildProject(project);
			assertHasNoBuildProblems(project);

			CountDownLatch latch = new CountDownLatch(numberOfThreads);
			List<CheckIfTypeExists> runnables = new ArrayList<>(numberOfThreads);
			for (int i = 0; i < numberOfThreads; ++i) {
				CheckIfTypeExists runnable = new CheckIfTypeExists(project, latch);
				runnables.add(runnable);
			}

			List<Thread> threads = startThreads(runnables);

			boolean interrupted = false;
			for (Thread thread : threads) {
				try {
					thread.join();
				} catch (InterruptedException e) {
					// we join all threads regardless of interruption, to be sure we don't leave running threads after this method done
					interrupted = true;
				}
			}
			assertFalse("waiting on test threads to finish must not be interrupted", interrupted);

			for (CheckIfTypeExists runnable : runnables) {
				assertTrue("expected type for test source to exist, despite concurrent access to JavaModelManager", runnable.typeExists);
			}
		} finally {
			deleteProject(PROJECT_NAME);
		}
	}

	private static List<Thread> startThreads(List<CheckIfTypeExists> runnables) {
		List<Thread> threads = new ArrayList<>(runnables.size());
		for (CheckIfTypeExists runnable : runnables) {
			Thread thread = new Thread(runnable);
			threads.add(thread);
			thread.start();
		}
		return threads;
	}

	class CheckIfTypeExists implements Runnable {

		private final IJavaProject project;
		private final CountDownLatch latch;

		boolean typeExists = false;

		CheckIfTypeExists(IJavaProject project, CountDownLatch latch) {
			this.project = project;
			this.latch = latch;
		}

		@Override
		public void run() {
			IType type = retrieveTestType(this.project);
			// we use a CountDownLatch to ensure the thread calls to IJavaElement.exists() are running as close together as possible
			this.latch.countDown();
			this.typeExists = type.exists();
		}
	}

	static IType retrieveTestType(IJavaProject project) {
		IFile jarResource = project.getProject().getFile("lib.jar");
		IPackageFragmentRoot root = project.getPackageFragmentRoot(jarResource);
		IPackageFragment packageFragment = root.getPackageFragment("p");
		IClassFile classFile = packageFragment.getClassFile("X.class");
		IOrdinaryClassFile ordinaryClassFile = (IOrdinaryClassFile) classFile;
		IType type = ordinaryClassFile.getType();
		return type;
	}

	private static void buildProject(IJavaProject javaProject) throws Exception {
		IProject project = javaProject.getProject();
		refreshProject(project);
		project.build(IncrementalProjectBuilder.CLEAN_BUILD, NULL_MONITOR);
		refreshProject(project);
		project.build(IncrementalProjectBuilder.FULL_BUILD, NULL_MONITOR);
		Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_BUILD, null);
		Indexer.getInstance().waitForIndex(null);
		refreshProject(project);
	}

	private static void refreshProject(IProject project) throws CoreException {
		project.refreshLocal(IResource.DEPTH_INFINITE, NULL_MONITOR);
		waitForManualRefresh();
	}

	private static void assertHasNoBuildProblems(IJavaProject javaProject) throws Exception {
		IProject project = javaProject.getProject();
		List<IMarker> modelProblems = getTestProjectErrorMarkers(project);
		assertTrue("expected no problems when building, but got:" + System.lineSeparator() + toString(modelProblems),
				modelProblems.isEmpty());
	}

	private static List<IMarker> getTestProjectErrorMarkers(IProject project) throws Exception {
		IMarker[] problemMarkers = project.findMarkers(null, true, IResource.DEPTH_ZERO);
		List<IMarker> errorMarkers = new ArrayList<>();
		for (IMarker problemMarker : problemMarkers) {
			int severity = problemMarker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO);
			if (severity == IMarker.SEVERITY_ERROR) {
				errorMarkers.add(problemMarker);
			}
		}
		return errorMarkers;
	}

	private static String toString(List<IMarker> markers) throws Exception {
		StringBuilder sb = new StringBuilder();
		for (IMarker marker : markers) {
			sb.append("Message: ");
			sb.append((marker.getAttribute(IMarker.MESSAGE)));
			sb.append(System.lineSeparator());
			sb.append("Location: ");
			sb.append(marker.getAttribute(IMarker.LOCATION));
			sb.append(System.lineSeparator());
			sb.append("Line: ");
			sb.append(marker.getAttribute(IMarker.LINE_NUMBER));
			sb.append(System.lineSeparator());
		}
		String fatalProblemsAsText = sb.toString();
		return fatalProblemsAsText;
	}
}
