/*******************************************************************************
 *  Copyright (c) 2003, 2012 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *     IBM - Initial API and implementation
 *******************************************************************************/
package org.eclipse.core.internal.jobs;

import java.util.*;
import org.eclipse.core.internal.runtime.RuntimeLog;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;

/**
 * Implicit jobs are jobs that are running by virtue of a JobManager.begin/end
 * pair. They act like normal jobs, except they are tied to an arbitrary thread
 * of the client's choosing, and they can be nested.
 * @ThreadSafe
 */
class ImplicitJobs {

	/**
	 * Cached unused instance that can be reused
	 * @GuardedBy("this")
	 */
	private ThreadJob jobCache = null;
	protected JobManager manager;

	/**
	 * Set of suspended scheduling rules.
	 * @GuardedBy("this")
	 */
	private final Set<ISchedulingRule> suspendedRules = new HashSet<>(20);

	/**
	 * Maps (Thread->ThreadJob), threads to the currently running job for that
	 * thread.
	 * @GuardedBy("this")
	 */
	private final Map<Thread, ThreadJob> threadJobs = new HashMap<>(20);

	ImplicitJobs(JobManager manager) {
		this.manager = manager;
	}

	/* (Non-javadoc)
	 * @see IJobManager#beginRule
	 */
	void begin(ISchedulingRule rule, IProgressMonitor monitor, boolean suspend) {
		if (JobManager.DEBUG_BEGIN_END)
			JobManager.debug("Begin rule: " + rule); //$NON-NLS-1$
		final Thread currentThread = Thread.currentThread();
		ThreadJob threadJob;
		synchronized (this) {
			threadJob = threadJobs.get(currentThread);
			if (threadJob != null) {
				//nested rule, just push on stack and return
				threadJob.push(rule);
				return;
			}
			//no need to schedule a thread job for a null rule
			if (rule == null)
				return;
			//create a thread job for this thread, use the rule from the real job if it has one
			Job realJob = manager.currentJob();
			if (realJob != null && realJob.getRule() != null)
				threadJob = newThreadJob(realJob.getRule());
			else {
				threadJob = newThreadJob(rule);
				threadJob.acquireRule = true;
			}
			//don't acquire rule if it is a suspended rule
			if (isSuspended(rule))
				threadJob.acquireRule = false;
			//indicate if it is a system job to ensure isBlocking works correctly
			threadJob.setRealJob(realJob);
			threadJob.setThread(currentThread);
		}
		try {
			threadJob.push(rule);
			//join the thread job outside sync block
			if (threadJob.acquireRule) {
				//no need to re-acquire any locks because the thread did not wait to get this lock
				if (manager.runNow(threadJob, false) == null)
					manager.getLockManager().addLockThread(Thread.currentThread(), rule);
				else
					threadJob = ThreadJob.joinRun(threadJob, monitor);
			}
		} finally {
			//remember this thread job  - only do this
			//after the rule is acquired because it is ok for this thread to acquire
			//and release other rules while waiting.
			synchronized (this) {
				threadJobs.put(currentThread, threadJob);
				if (suspend)
					suspendedRules.add(rule);
			}
		}
	}

	/* (Non-javadoc)
	 * @see IJobManager#endRule
	 */
	synchronized void end(ISchedulingRule rule, boolean resume) {
		if (JobManager.DEBUG_BEGIN_END)
			JobManager.debug("End rule: " + rule); //$NON-NLS-1$
		ThreadJob threadJob = threadJobs.get(Thread.currentThread());
		if (threadJob == null)
			Assert.isLegal(rule == null, "endRule without matching beginRule: " + rule); //$NON-NLS-1$
		else if (threadJob.pop(rule)) {
			endThreadJob(threadJob, resume);
		}
	}

	/**
	 * Called when a worker thread has finished running a job. At this
	 * point, the worker thread must not own any scheduling rules
	 * @param lastJob The last job to run in this thread
	 */
	void endJob(InternalJob lastJob) {
		final Thread currentThread = Thread.currentThread();
		IStatus error;
		synchronized (this) {
			ThreadJob threadJob = threadJobs.get(currentThread);
			if (threadJob == null) {
				if (lastJob.getRule() != null)
					notifyWaitingThreadJobs(lastJob);
				return;
			}
			String msg = "Worker thread ended job: " + lastJob + ", but still holds rule: " + threadJob; //$NON-NLS-1$ //$NON-NLS-2$
			error = new Status(IStatus.ERROR, JobManager.PI_JOBS, 1, msg, null);
			//end the thread job
			endThreadJob(threadJob, false);
		}
		try {
			RuntimeLog.log(error);
		} catch (RuntimeException e) {
			//failed to log, so print to console instead
			System.err.println(error.getMessage());
		}
	}

	/**
	 * @GuardedBy("this")
	 */
	private void endThreadJob(ThreadJob threadJob, boolean resume) {
		Thread currentThread = Thread.currentThread();
		//clean up when last rule scope exits
		threadJobs.remove(currentThread);
		ISchedulingRule rule = threadJob.getRule();
		if (resume && rule != null)
			suspendedRules.remove(rule);
		//if this job had a rule, then we are essentially releasing a lock
		//note it is safe to do this even if the acquire was aborted
		if (threadJob.acquireRule) {
			manager.getLockManager().removeLockThread(currentThread, rule);
			notifyWaitingThreadJobs(threadJob);
		}
		//if the job was started, we need to notify job manager to end it
		if (threadJob.isRunning())
			manager.endJob(threadJob, Status.OK_STATUS, false);
		recycle(threadJob);
	}

	/**
	 * Returns true if this rule has been suspended, and false otherwise.
	 * @GuardedBy("this")
	 */
	private boolean isSuspended(ISchedulingRule rule) {
		if (suspendedRules.size() == 0)
			return false;
		for (Iterator<ISchedulingRule> it = suspendedRules.iterator(); it.hasNext();)
			if (it.next().contains(rule))
				return true;
		return false;
	}

	/**
	 * Returns a new or reused ThreadJob instance.
	 * @GuardedBy("this")
	 */
	private ThreadJob newThreadJob(ISchedulingRule rule) {
		if (jobCache != null) {
			ThreadJob job = jobCache;
			// calling setRule will try to acquire JobManager.lock, breaking
			// lock acquisition protocol. Since we managing this special job
			// ourselves we can call internalSetRule
			((InternalJob) job).internalSetRule(rule);
			job.acquireRule = job.isRunning = false;
			job.realJob = null;
			jobCache = null;
			return job;
		}
		return new ThreadJob(rule);
	}

	/**
	 * A job has just finished that was holding a scheduling rule, and the
	 * scheduling rule is now free.  Wake any blocked thread jobs so they can
	 * compete for the newly freed lock
	 */
	void notifyWaitingThreadJobs(InternalJob job) {
		synchronized (job.jobStateLock) {
			job.jobStateLock.notifyAll();
		}
	}

	/**
	 * Indicates that a thread job is no longer in use and can be reused.
	 * @GuardedBy("this")
	 */
	private void recycle(ThreadJob job) {
		if (jobCache == null && job.recycle())
			jobCache = job;
	}

	/**
	 * Implements IJobManager#resume(ISchedulingRule)
	 * @param rule
	 */
	void resume(ISchedulingRule rule) {
		//resume happens as a consequence of freeing the last rule in the stack
		end(rule, true);
		if (JobManager.DEBUG_BEGIN_END)
			JobManager.debug("Resume rule: " + rule); //$NON-NLS-1$
	}

	/**
	 * Implements IJobManager#suspend(ISchedulingRule, IProgressMonitor)
	 * @param rule
	 * @param monitor
	 */
	void suspend(ISchedulingRule rule, IProgressMonitor monitor) {
		if (JobManager.DEBUG_BEGIN_END)
			JobManager.debug("Suspend rule: " + rule); //$NON-NLS-1$
		//the suspend job will be remembered once the rule is acquired
		begin(rule, monitor, true);
	}

	/**
	 * Implements IJobManager#transferRule(ISchedulingRule, Thread)
	 */
	synchronized void transfer(ISchedulingRule rule, Thread destinationThread) {
		//nothing to do for null
		if (rule == null)
			return;
		final Thread currentThread = Thread.currentThread();
		//nothing to do if transferring to the same thread
		if (currentThread == destinationThread)
			return;
		//ensure destination thread doesn't already have a rule
		ThreadJob target = threadJobs.get(destinationThread);
		Assert.isLegal(target == null, "Transfer rule to job that already owns a rule"); //$NON-NLS-1$
		//ensure calling thread owns the job being transferred
		ThreadJob source = threadJobs.get(currentThread);
		Assert.isNotNull(source, "transferRule without beginRule"); //$NON-NLS-1$
		Assert.isLegal(source.getRule() == rule, "transferred rule " + rule + " does not match beginRule: " + source.getRule()); //$NON-NLS-1$ //$NON-NLS-2$		// transfer the thread job without ending it
		source.setThread(destinationThread);
		threadJobs.remove(currentThread);
		threadJobs.put(destinationThread, source);
		// transfer lock
		if (source.acquireRule) {
			manager.getLockManager().removeLockThread(currentThread, rule);
			manager.getLockManager().addLockThread(destinationThread, rule);
		}
		// Wake up any blocked jobs (waiting within yield or joinRun) waiting on
		// this rule
		notifyWaitingThreadJobs(source);
	}

	synchronized void removeWaiting(ThreadJob threadJob) {
		synchronized (((InternalJob) threadJob).jobStateLock) {
			threadJob.isWaiting = false;
			notifyWaitingThreadJobs(threadJob);
			((InternalJob) threadJob).setWaitQueueStamp(InternalJob.T_NONE);
		}
		manager.dequeue(manager.waitingThreadJobs, threadJob);
	}

	synchronized void addWaiting(ThreadJob threadJob) {
		synchronized (((InternalJob) threadJob).jobStateLock) {
			threadJob.isWaiting = true;
			notifyWaitingThreadJobs(threadJob);
			((InternalJob) threadJob).setWaitQueueStamp(manager.waitQueueCounter.increment());
		}
		manager.enqueue(manager.waitingThreadJobs, threadJob);
	}

	synchronized ThreadJob getThreadJob(Thread thread) {
		return threadJobs.get(thread);
	}

}
