/* ************************************************************************
#
#  DivConq
#
#  http://divconq.com/
#
#  Copyright:
#    Copyright 2012 eTimeline, LLC. All rights reserved.
#
#  License:
#    See the license.txt file in the project's top-level directory for details.
#
#  Authors:
#    * Andy White
#
************************************************************************ */
package divconq.work;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import divconq.lang.TaskContext;

public class TaskInfo implements ITaskInfo {
	protected TaskContext context = null;
	protected IRunnable work = null;
	protected AtomicBoolean canceled = new AtomicBoolean();
	protected AtomicLong runcount = new AtomicLong();
	protected AtomicLong failcount = new AtomicLong();
	protected int slot = -1;
	
	public TaskInfo(IRunnable task) {
		this.work = task;
		this.context = TaskContext.get(); 
	}
	
	public TaskInfo(IRunnable task, TaskContext ctx) {
		this.work = task;
		this.context = ctx; 
	}
	
	@Override
	public TaskContext context() {
		return this.context;
	}

	@Override
	public void cancel() {
		this.canceled.set(true);
	}
	
	@Override
	public boolean canceled() {
		return this.canceled.get();
	}
	
	public long runCount() {
		return this.runcount.get();
	}
	
	@Override
	public boolean hasRun() {
		return (this.runcount.get() > 0);
	}
	
	@Override
	public void run() {
		if (this.canceled.get())
			return;
			
		TaskContext.set(this.context);
		//this.context.setThreadSlot(this.slot);		no good, TaskContext is not owned by one thread
		
		try {
			if (this.work != null)
				this.work.run(this);
			
			this.runcount.incrementAndGet();
		}
		catch (Exception x) {
			System.out.println("Work pool caught exception: " + x);
			
			this.failcount.incrementAndGet();
		}
		finally {
			//this.context.setThreadSlot(-1);
			TaskContext.clear();
		}
	}

	@Override
	public void setThreadSlot(int slot) {
		this.slot = slot;
	}
}
