/*******************************************************************************
 * Copyright (c) 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.core.tests.runtime.jobs;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

/**
 * Test for bug 574883
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class Bug_574883 extends AbstractJobManagerTest {

	static class SerialExecutor extends Job {

		private final List<Runnable> queue;
		private final Object myFamily;

		/**
		 * @param jobName descriptive job name
		 * @param family  non null object to control this job execution
		 **/
		public SerialExecutor(String jobName, Object family) {
			super(jobName);
			Assert.isNotNull(family);
			this.myFamily = family;
			this.queue = Collections.synchronizedList(new LinkedList<>());
			setSystem(true);
		}

		@Override
		public boolean belongsTo(Object family) {
			return myFamily == family;
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			Runnable action = queue.remove(0);
			try {
				if (action != null) {
					action.run();
				}
			} finally {
				if (!queue.isEmpty()) {
					// this call confuses JobManager and causes bug 574883 if the action above
					// runs *too fast*
					schedule();
				}
			}
			return Status.OK_STATUS;
		}

		/**
		 * Enqueue an action asynchronously.
		 */
		public void schedule(Runnable action) {
			queue.add(action);
			schedule();
		}
	}

	final int RUNS = 100_000;
	final int processors = Runtime.getRuntime().availableProcessors();

	@Test
	public void testReschedulingLambda() throws InterruptedException {
		// Executor has to execute every task. Even when they are scheduled fast
		// and execute fast
		SerialExecutor serialExecutor = new SerialExecutor("test", this);
		AtomicInteger executions = new AtomicInteger();
		for (int i = 0; i < RUNS; i++) {
			serialExecutor.schedule(() -> executions.incrementAndGet());
		}
		Job.getJobManager().join(this, null);
		Job[] jobs = Job.getJobManager().find(this);
		int length = jobs.length;
		int firstState = executions.get();
		try {
			if (length > 0) {
				// Check if that still would work?
				Job.getJobManager().join(this, null);
				if (Job.getJobManager().find(this).length > 0) {
					fail("Job still running after second join, executed before: " + firstState + ", executed now: "
							+ executions.get() + ", cpu: " + processors);
				}
			}
			assertEquals("Job still running after first join, executed: " + firstState + ", cpu: " + processors, 0,
					length);
			assertEquals(RUNS, executions.get());
		} catch (Throwable t) {
			// TODO: print the fail only, as long as bug 574883 is not fixed yet
			t.printStackTrace(System.out);
			t.printStackTrace(System.err);
		}
	}

	@Test
	public void testReschedulingMethodRef() throws InterruptedException {
		// Executor has to execute every task. Even when they are scheduled fast
		// and execute fast
		SerialExecutor serialExecutor = new SerialExecutor("test", this);
		AtomicInteger executions = new AtomicInteger();
		for (int i = 0; i < RUNS; i++) {
			serialExecutor.schedule(executions::incrementAndGet);
		}
		Job.getJobManager().join(this, null);
		Job[] jobs = Job.getJobManager().find(this);
		int length = jobs.length;
		int firstState = executions.get();
		try {
			if (length > 0) {
				// Check if that still would work?
				Job.getJobManager().join(this, null);
				if (Job.getJobManager().find(this).length > 0) {
					fail("Job still running after second join, executed before: " + firstState + ", executed now: "
							+ executions.get() + ", cpu: " + processors);
				}
			}
			assertEquals("Job still running after first join, executed: " + firstState + ", cpu: " + processors, 0,
					length);
			assertEquals(RUNS, executions.get());
		} catch (Throwable t) {
			// TODO: print the fail only, as long as bug 574883 is not fixed yet
			t.printStackTrace(System.out);
			t.printStackTrace(System.err);
		}
	}

	/**
	 * This test always passes because it does a bit more work as both tests above
	 * inside run method
	 */
	@Test
	public void testReschedulingSomeMoreWork() throws InterruptedException {
		// Executor has to execute every task. Even when they are scheduled fast
		// and execute fast
		SerialExecutor serialExecutor = new SerialExecutor("test", this);
		AtomicInteger executions = new AtomicInteger();
		AtomicLong garbage = new AtomicLong(42);
		for (int i = 0; i < RUNS; i++) {
			serialExecutor.schedule(() -> {
				executions.incrementAndGet();
				// just consume some more CPU cycles
				garbage.getAndUpdate(x -> (long) (x + Math.sin(x) * 100));
			});
		}
		Job.getJobManager().join(this, null);
		Job[] jobs = Job.getJobManager().find(this);
		int length = jobs.length;
		int firstState = executions.get();
		System.out.println(garbage);
		try {
		if (length > 0) {
				// Check if that still would work?
				Job.getJobManager().join(this, null);
				if (Job.getJobManager().find(this).length > 0) {
					fail("Job still running after second join, executed before: " + firstState + ", executed now: "
							+ executions.get() + ", cpu: " + processors);
				}
			}
			assertEquals("Job still running after first join, executed: " + firstState + ", cpu: " + processors, 0,
					length);
			assertEquals(RUNS, executions.get());
		} catch (Throwable t) {
			// TODO: print the fail only, as long as bug 574883 is not fixed yet
			t.printStackTrace(System.out);
			t.printStackTrace(System.err);
		}
	}

	@Test
	public void testNow() throws Exception {
		AtomicInteger executions = new AtomicInteger();
		for (int i = 0; i < RUNS; i++) {
			long t1 = now();
			((Runnable) () -> executions.incrementAndGet()).run();
			long t2 = now();
			long diff = t2 - t1;
			assertTrue("Time should not go back: " + diff + " at: " + i, diff >= 0);
		}
		assertEquals(RUNS, executions.get());
	}
}
