/*******************************************************************************
 * Copyright (c) 2008, 2016 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
 *     Technical University Berlin - extended API and implementation
 *******************************************************************************/

package org.eclipse.jdt.internal.compiler;

import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.util.Messages;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;

public class ProcessTaskManager implements Runnable {

	Compiler compiler;
	private int unitIndex;
	private Thread processingThread;
	CompilationUnitDeclaration unitToProcess;
	private Throwable caughtException;

	// queue
	volatile int currentIndex, availableIndex, size, sleepCount;
	CompilationUnitDeclaration[] units;

	public static final int PROCESSED_QUEUE_SIZE = 12;

//{ObjectTeams:
	private Config sharedConfig;
	/* This method is also a hook for jdt.ui.adaptor's ProjectWatcher. */
	private void setConfig(Config config) {
		this.sharedConfig= config;
	}
// SH}

	public ProcessTaskManager(Compiler compiler, int startingIndex) {
	this.compiler = compiler;
	this.unitIndex = startingIndex;

	this.currentIndex = 0;
	this.availableIndex = 0;
	this.size = PROCESSED_QUEUE_SIZE;
	this.sleepCount = 0; // 0 is no one, +1 is the processing thread & -1 is the writing/main thread
	this.units = new CompilationUnitDeclaration[this.size];

	synchronized (this) {
		this.processingThread = new Thread(this, "Compiler Processing Task"); //$NON-NLS-1$
//{ObjectTeams:
		setConfig(Config.getConfig());
// SH}
		this.processingThread.setDaemon(true);
		this.processingThread.start();
	}
}

// add unit to the queue - wait if no space is available
private synchronized void addNextUnit(CompilationUnitDeclaration newElement) {
	while (this.units[this.availableIndex] != null) {
		//System.out.print('a');
		//if (this.sleepCount < 0) throw new IllegalStateException(Integer.valueOf(this.sleepCount).toString());
		this.sleepCount = 1;
		try {
			wait(250);
		} catch (InterruptedException ignore) {
			// ignore
		}
		this.sleepCount = 0;
	}

	this.units[this.availableIndex++] = newElement;
	if (this.availableIndex >= this.size)
		this.availableIndex = 0;
	if (this.sleepCount <= -1)
		notify(); // wake up writing thread to accept next unit - could be the last one - must avoid deadlock
}

public CompilationUnitDeclaration removeNextUnit() throws Error {
	CompilationUnitDeclaration next = null;
	boolean yield = false;
	synchronized (this) {
		next = this.units[this.currentIndex];
		if (next == null || this.caughtException != null) {
			do {
				if (this.processingThread == null) {
					if (this.caughtException != null) {
						// rethrow the caught exception from the processingThread in the main compiler thread
						if (this.caughtException instanceof Error)
							throw (Error) this.caughtException;
						throw (RuntimeException) this.caughtException;
					}
					return null;
				}
				//System.out.print('r');
				//if (this.sleepCount > 0) throw new IllegalStateException(Integer.valueOf(this.sleepCount).toString());
				this.sleepCount = -1;
				try {
					wait(100);
				} catch (InterruptedException ignore) {
					// ignore
				}
				this.sleepCount = 0;
				next = this.units[this.currentIndex];
			} while (next == null);
		}

		this.units[this.currentIndex++] = null;
		if (this.currentIndex >= this.size)
			this.currentIndex = 0;
		if (this.sleepCount >= 1 && ++this.sleepCount > 4) {
			notify(); // wake up processing thread to add next unit but only after removing some elements first
			yield = this.sleepCount > 8;
		}
	}
	if (yield)
		Thread.yield();
	return next;
}

@Override
public void run() {
//{ObjectTeams:
	Config.addConfig(this.sharedConfig);
// SH}
	boolean noAnnotations = this.compiler.annotationProcessorManager == null;
	while (this.processingThread != null) {
		this.unitToProcess = null;
		int index = -1;
		boolean cleanup = noAnnotations || this.compiler.shouldCleanup(this.unitIndex);
		try {
			synchronized (this) {
				if (this.processingThread == null) return;

				this.unitToProcess = this.compiler.getUnitToProcess(this.unitIndex);
				if (this.unitToProcess == null) {
					this.processingThread = null;
					return;
				}
				index = this.unitIndex++;
				if (this.unitToProcess.compilationResult.hasBeenAccepted)
					continue;
			}

			try {
				this.compiler.reportProgress(Messages.bind(Messages.compilation_processing, new String(this.unitToProcess.getFileName())));
				if (this.compiler.options.verbose)
					this.compiler.out.println(
						Messages.bind(Messages.compilation_process,
						new String[] {
							String.valueOf(index + 1),
							String.valueOf(this.compiler.totalUnits),
							new String(this.unitToProcess.getFileName())
						}));
				this.compiler.process(this.unitToProcess, index);
			} finally {
				// cleanup compilation unit result, but only if not annotation processed.
				if (this.unitToProcess != null && cleanup)
					this.unitToProcess.cleanUp();
			}

			addNextUnit(this.unitToProcess);
		} catch (Error e) {
			synchronized (this) {
				this.processingThread = null;
				this.caughtException = e;
			}
			return;
		} catch (RuntimeException e) {
			synchronized (this) {
				this.processingThread = null;
				this.caughtException = e;
			}
			return;
		}
	}
}

public void shutdown() {
	try {
		Thread t = null;
		synchronized (this) {
			if (this.processingThread != null) {
				t = this.processingThread;
				this.processingThread = null;
				notifyAll();
			}
		}
		if (t != null)
			t.join(250); // do not wait forever
	} catch (InterruptedException ignored) {
		// ignore
	}
}
}
