/*******************************************************************************
 * Copyright (c) 2003, 2015 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 - Initial API and implementation
 *******************************************************************************/
package org.eclipse.core.tests.runtime.jobs;

import java.util.ArrayList;
import junit.framework.TestCase;
import org.eclipse.core.internal.jobs.LockManager;
import org.eclipse.core.internal.jobs.OrderedLock;
import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.core.runtime.jobs.LockListener;
import org.eclipse.core.tests.harness.TestBarrier;

/**
 * Tests implementation of ILock objects
 */
public class OrderedLockTest extends TestCase {
	public OrderedLockTest() {
		super(null);
	}

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

	/**
	 * Creates n runnables on the given lock and adds them to the given list.
	 */
	private void createRunnables(ILock[] locks, int n, ArrayList<LockAcquiringRunnable> allRunnables) {
		for (int i = 0; i < n; i++)
			allRunnables.add(new LockAcquiringRunnable(locks));
	}

	private void kill(ArrayList<LockAcquiringRunnable> allRunnables) {
		for (LockAcquiringRunnable lockAcquiringRunnable : allRunnables) {
			lockAcquiringRunnable.kill();
		}
	}

	public void testComplex() {
		ArrayList<LockAcquiringRunnable> allRunnables = new ArrayList<>();
		LockManager manager = new LockManager();
		OrderedLock lock1 = manager.newLock();
		OrderedLock lock2 = manager.newLock();
		OrderedLock lock3 = manager.newLock();
		createRunnables(new ILock[] {lock1, lock2, lock3}, 5, allRunnables);
		createRunnables(new ILock[] {lock3, lock2, lock1}, 5, allRunnables);
		createRunnables(new ILock[] {lock1, lock3, lock2}, 5, allRunnables);
		createRunnables(new ILock[] {lock2, lock3, lock1}, 5, allRunnables);
		start(allRunnables);
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
		}
		kill(allRunnables);
		for (LockAcquiringRunnable runnable : allRunnables) {
			runnable.isDone();
		}
		//the underlying array has to be empty
		assertTrue("Locks not removed from graph.", manager.isEmpty());
	}

	public void testSimple() {
		ArrayList<LockAcquiringRunnable> allRunnables = new ArrayList<>();
		LockManager manager = new LockManager();
		OrderedLock lock1 = manager.newLock();
		OrderedLock lock2 = manager.newLock();
		OrderedLock lock3 = manager.newLock();
		createRunnables(new ILock[] {lock1, lock2, lock3}, 1, allRunnables);
		createRunnables(new ILock[] {lock3, lock2, lock1}, 1, allRunnables);
		start(allRunnables);
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
		}
		kill(allRunnables);
		for (LockAcquiringRunnable runnable : allRunnables) {
			runnable.isDone();
		}
		//the underlying array has to be empty
		assertTrue("Locks not removed from graph.", manager.isEmpty());
	}

	public void testLockAcquireInterrupt() throws InterruptedException {
		final TestBarrier barrier = new TestBarrier();
		LockManager manager = new LockManager();
		final ILock lock = manager.newLock();
		final boolean[] wasInterupted = new boolean[] {false};
		Thread t = new Thread() {
			@Override
			public void run() {
				barrier.setStatus(TestBarrier.STATUS_RUNNING);
				barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_START);
				barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
				lock.acquire();
				wasInterupted[0] = Thread.currentThread().isInterrupted();
				lock.release();
			}
		};
		//schedule and wait for thread to start
		t.start();
		barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
		//acquire the lock and let the thread proceed
		lock.acquire();
		barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_START);
		//make sure thread is blocked
		barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
		Thread.sleep(500);
		t.interrupt();
		lock.release();
		t.join();
		assertTrue("1.0", wasInterupted[0]);
	}

	/**
	 * test that an acquire call that times out does not
	 * become the lock owner (regression test)
	 */
	public void testLockTimeout() {
		//create a new lock manager and 1 lock
		final LockManager manager = new LockManager();
		final OrderedLock lock = manager.newLock();
		//status array for communicating between threads
		final int[] status = {TestBarrier.STATUS_START};
		//array to end a runnable after it is no longer needed
		final boolean[] alive = {true};

		//first runnable which is going to hold the created lock
		Runnable getLock = () -> {
			lock.acquire();
			status[0] = TestBarrier.STATUS_RUNNING;
			while (alive[0]) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
				}
			}
			lock.release();
			status[0] = TestBarrier.STATUS_DONE;
		};

		//second runnable which is going to try and acquire the given lock and then time out
		Runnable tryForLock = () -> {
			boolean success = false;
			try {
				success = lock.acquire(100);
			} catch (InterruptedException e) {
			}
			assertTrue("1.0", !success);
			assertTrue("1.1", !manager.isLockOwner());
			status[0] = TestBarrier.STATUS_WAIT_FOR_DONE;
		};

		Thread first = new Thread(getLock);
		Thread second = new Thread(tryForLock);

		//start the first thread and wait for it to acquire the lock
		first.start();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_RUNNING);
		//start the second thread, make sure the assertion passes
		second.start();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_WAIT_FOR_DONE);
		//let the first thread die
		alive[0] = false;
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_DONE);
		//the underlying array has to be empty
		assertTrue("Locks not removed from graph.", manager.isEmpty());
	}

	/**
	 * test that when a Lock Listener forces the Lock Manager to grant a lock
	 * to a waiting thread, that other threads in the queue don't get disposed (regression test)
	 */
	public void testLockRequestDisappearence() {
		//create a new lock manager and 1 lock
		final LockManager manager = new LockManager();
		final OrderedLock lock = manager.newLock();
		//status array for communicating between threads
		final int[] status = {TestBarrier.STATUS_WAIT_FOR_START, TestBarrier.STATUS_WAIT_FOR_START};

		//first runnable which is going to hold the created lock
		Runnable getLock = () -> {
			lock.acquire();
			status[0] = TestBarrier.STATUS_START;
			TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_RUNNING);
			lock.release();
			status[0] = TestBarrier.STATUS_DONE;
		};

		//second runnable which is going to submit a request for this lock and wait until it is available
		Runnable waitForLock = () -> {
			status[1] = TestBarrier.STATUS_START;
			lock.acquire();
			assertTrue("1.0", manager.isLockOwner());
			lock.release();
			status[1] = TestBarrier.STATUS_DONE;

		};

		//third runnable which is going to submit a request for this lock but not wait
		//because the hook is going to force it to be given the lock (implicitly)
		Runnable forceGetLock = () -> {
			lock.acquire();
			lock.release();
			status[0] = TestBarrier.STATUS_WAIT_FOR_DONE;
		};

		//a locklistener to force lock manager to give the lock to the third runnable (implicitly)
		LockListener listener = new LockListener() {
			@Override
			public boolean aboutToWait(Thread lockOwner) {
				return true;
			}
		};

		//assign each runnable to a separate thread
		Thread first = new Thread(getLock);
		Thread second = new Thread(waitForLock);
		Thread third = new Thread(forceGetLock);

		//start the first thread and wait for it to acquire the lock
		first.start();
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_START);
		//start the second thread, make sure it is added to the lock wait queue
		second.start();
		TestBarrier.waitForStatus(status, 1, TestBarrier.STATUS_START);

		//assign our listener to the manager
		manager.setLockListener(listener);
		//start the third thread
		third.start();
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_WAIT_FOR_DONE);

		//let the first runnable complete
		status[0] = TestBarrier.STATUS_RUNNING;
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_DONE);

		//now wait for the second runnable to get the lock, and have the assertion pass
		TestBarrier.waitForStatus(status, 1, TestBarrier.STATUS_DONE);

		//the underlying array has to be empty
		assertTrue("Locks not removed from graph.", manager.isEmpty());
	}

	private void start(ArrayList<LockAcquiringRunnable> allRunnables) {
		for (LockAcquiringRunnable lockAcquiringRunnable : allRunnables) {
			new Thread(lockAcquiringRunnable).start();
		}
	}
}
