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

import java.util.*;

import org.eclipse.core.internal.runtime.Assert;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.*;

/**
 * Internal implementation class for jobs.
 */
public abstract class InternalJob extends PlatformObject implements Comparable {
	/** 
	 * Job state code (value 8) indicating that a job is blocked by another currently
	 * running job.  From an API point of view, this is the same as WAITING.
	 */
	public static final int BLOCKED = 0x08;
	/** 
	 * Job state code (value 16) indicating that a job has been removed from
	 * the wait queue and is about to start running. From an API point of view, 
	 * this is the same as RUNNING.
	 */
	public static final int ABOUT_TO_RUN = 0x10;

	//flag mask bits
	private static final int M_STATE = 0xFF;
	private static final int M_SYSTEM = 0x0100;
	private static final int M_USER = 0x0200;

	private static final JobManager manager = JobManager.getInstance();
	private static int nextJobNumber = 0;

	/**
	 * Start time constant indicating a job should be started at
	 * a time in the infinite future, causing it to sleep forever.
	 */
	protected static final long T_INFINITE = Long.MAX_VALUE;
	/**
	 * Start time constant indicating that the job has no start time.
	 */
	protected static final long T_NONE = -1;

	private volatile int flags = Job.NONE;
	private final int jobNumber = nextJobNumber++;
	private List listeners;
	private IProgressMonitor monitor;
	private String name;
	/**
	 * The job ahead of me in a queue or list.
	 */
	private InternalJob next;
	/**
	 * The job behind me in a queue or list.
	 */
	private InternalJob previous;
	private int priority = Job.LONG;
	/**
	 * Arbitrary properties (key,value) pairs, attached
	 * to a job instance by a third party.
	 */
	private ObjectMap properties;
	private IStatus result;
	private ISchedulingRule schedulingRule;
	/**
	 * If the job is waiting, this represents the time the job should start by.  
	 * If this job is sleeping, this represents the time the job should wake up.
	 * If this job is running, this represents the delay automatic rescheduling,
	 * or -1 if the job should not be rescheduled.
	 */
	private long startTime;
	/*
	 * The thread that is currently running this job
	 */
	private volatile Thread thread = null;

	protected InternalJob(String name) {
		Assert.isNotNull(name);
		this.name = name;
	}

	/* (non-Javadoc)
	 * @see Job#addJobListener(IJobChangeListener)
	 */
	protected void addJobChangeListener(IJobChangeListener listener) {
		if (listeners == null)
			listeners = Collections.synchronizedList(new ArrayList(2));
		listeners.add(listener);
	}

	/**
	 * Adds an entry at the end of the list of which this item is the head.
	 */
	final void addLast(InternalJob entry) {
		if (previous == null) {
			previous = entry;
			entry.next = this;
			entry.previous = null;
		} else {
			Assert.isTrue(previous.next() == this);
			previous.addLast(entry);
		}
	}

	protected boolean belongsTo(Object family) {
		return false;
	}

	protected boolean cancel() {
		return manager.cancel(this);
	}

	public final int compareTo(Object otherJob) {
		return (int) (((InternalJob) otherJob).startTime - startTime);
	}

	protected void done(IStatus result) {
		manager.endJob(this, result, true);
	}

	/**
	 * Returns the job listeners that are only listening to this job.  Returns null
	 * if this job has no listeners.
	 */
	final List getListeners() {
		return listeners;
	}

	protected String getName() {
		return name;
	}

	protected int getPriority() {
		return priority;
	}

	final IProgressMonitor getProgressMonitor() {
		return monitor;
	}

	/* (non-Javadoc)
	 * @see Job#getProperty
	 */
	protected Object getProperty(QualifiedName key) {
		// thread safety: (Concurrency001 - copy on write)
		Map temp = properties;
		if (temp == null)
			return null;
		return temp.get(key);
	}

	/* (non-Javadoc)
	 * @see Job#getResult
	 */
	protected IStatus getResult() {
		return result;
	}

	/* (non-Javadoc)
	 * @see Job#getRule
	 */
	protected ISchedulingRule getRule() {
		return schedulingRule;
	}

	/*package*/
	final long getStartTime() {
		return startTime;
	}

	protected int getState() {
		int state = flags & M_STATE;
		switch (state) {
			//blocked state is equivalent to waiting state for clients
			case BLOCKED :
				return Job.WAITING;
			case ABOUT_TO_RUN :
				return Job.RUNNING;
			default :
				return state;
		}
	}

	/* (non-javadoc)
	 * @see Job.getThread
	 */
	protected Thread getThread() {
		return thread;
	}

	final int internalGetState() {
		return flags & M_STATE;
	}

	/*
	 * Must be called from JobManager#setPriority
	 */
	final void internalSetPriority(int newPriority) {
		this.priority = newPriority;
	}

	/*
	 * Must be called from JobManager#setRule
	 */
	final void internalSetRule(ISchedulingRule rule) {
		this.schedulingRule = rule;
	}

	/*
	 * Must be called from JobManager#changeState
	 */
	final void internalSetState(int i) {
		flags = (flags & ~M_STATE) | i;
	}

	/* (non-Javadoc)
	 * @see Job#isBlocking
	 */
	protected boolean isBlocking() {
		return manager.isBlocking(this);
	}

	/**
	 * Returns true if this job conflicts with the given job, and false otherwise.
	 */
	final boolean isConflicting(InternalJob otherJob) {
		ISchedulingRule otherRule = otherJob.getRule();
		if (schedulingRule == null || otherRule == null)
			return false;
		//if one of the rules is a compound rule, it must be asked the question.
		if (schedulingRule.getClass() == MultiRule.class)
			return schedulingRule.isConflicting(otherRule);
		else
			return otherRule.isConflicting(schedulingRule);
	}

	/* (non-javadoc)
	 * @see Job.isSystem
	 */
	protected boolean isSystem() {
		return (flags & M_SYSTEM) != 0;
	}

	/* (non-javadoc)
	 * @see Job.isUser
	 */
	protected boolean isUser() {
		return (flags & M_USER) != 0;
	}

	protected void join() throws InterruptedException {
		manager.join(this);
	}

	/**
	 * Returns the next entry (ahead of this one) in the list, or null if there is no next entry
	 */
	final InternalJob next() {
		return next;
	}

	/**
	 * Returns the previous entry (behind this one) in the list, or null if there is no previous entry
	 */
	final InternalJob previous() {
		return previous;
	}

	/**
	 * Removes this entry from any list it belongs to.  Returns the receiver.
	 */
	final InternalJob remove() {
		if (next != null)
			next.setPrevious(previous);
		if (previous != null)
			previous.setNext(next);
		next = previous = null;
		return this;
	}

	/* (non-Javadoc)
	 * @see Job#removeJobListener(IJobChangeListener)
	 */
	protected void removeJobChangeListener(IJobChangeListener listener) {
		if (listeners != null)
			listeners.remove(listener);
		if (listeners.isEmpty())
			listeners = null;
	}

	protected abstract IStatus run(IProgressMonitor monitor);

	protected void schedule(long delay) {
		manager.schedule(this, delay);
	}

	protected void setName(String name) {
		Assert.isNotNull(name);
		this.name = name;
	}

	final void setNext(InternalJob entry) {
		this.next = entry;
	}

	final void setPrevious(InternalJob entry) {
		this.previous = entry;
	}

	protected void setPriority(int newPriority) {
		switch (newPriority) {
			case Job.INTERACTIVE :
			case Job.SHORT :
			case Job.LONG :
			case Job.BUILD :
			case Job.DECORATE :
				manager.setPriority(this, newPriority);
				break;
			default :
				throw new IllegalArgumentException(String.valueOf(newPriority));
		}
	}

	protected void setProgressGroup(IProgressMonitor group, int ticks) {
		Assert.isNotNull(group);
		IProgressMonitor result = manager.createMonitor(this, group, ticks);
		if (result != null)
			setProgressMonitor(result);
	}

	final void setProgressMonitor(IProgressMonitor monitor) {
		this.monitor = monitor;
	}

	/* (non-Javadoc)
	 * @see Job#setProperty
	 */
	protected void setProperty(QualifiedName key, Object value) {
		// thread safety: (Concurrency001 - copy on write)
		if (value == null) {
			if (properties == null)
				return;
			ObjectMap temp = (ObjectMap) properties.clone();
			temp.remove(key);
			if (temp.isEmpty())
				properties = null;
			else
				properties = temp;
		} else {
			ObjectMap temp = properties;
			if (temp == null)
				temp = new ObjectMap(5);
			else
				temp = (ObjectMap) properties.clone();
			temp.put(key, value);
			properties = temp;
		}
	}

	final void setResult(IStatus result) {
		this.result = result;
	}

	protected void setRule(ISchedulingRule rule) {
		manager.setRule(this, rule);
	}

	final void setStartTime(long time) {
		startTime = time;
	}

	/* (non-javadoc)
	 * @see Job.setSystem
	 */
	protected void setSystem(boolean value) {
		if (getState() != Job.NONE)
			throw new IllegalStateException();
		flags = value ? flags | M_SYSTEM : flags & ~M_SYSTEM;
	}

	/* (non-javadoc)
	 * @see Job.setThread
	 */
	protected void setThread(Thread thread) {
		this.thread = thread;
	}

	/* (non-javadoc)
	 * @see Job.setUser
	 */
	protected void setUser(boolean value) {
		if (getState() != Job.NONE)
			throw new IllegalStateException();
		flags = value ? flags | M_USER : flags & ~M_USER;
	}

	/* (Non-javadoc)
	 * @see Job#shouldSchedule
	 */
	protected boolean shouldSchedule() {
		return true;
	}

	protected boolean sleep() {
		return manager.sleep(this);
	}

	public String toString() {
		return getName() + "(" + jobNumber + ")"; //$NON-NLS-1$//$NON-NLS-2$
	}

	protected void wakeUp(long delay) {
		manager.wakeUp(this, delay);
	}
}