package com.hammurapi.reasoning.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;

import com.hammurapi.util.concurrent.NonBlockingNotifyingFutureTask;
import com.hammurapi.util.concurrent.TaskCounter;

public class NonBlockingPriorityNotifyingFutureTask<V, A> extends NonBlockingNotifyingFutureTask<V> implements Comparable<NonBlockingPriorityNotifyingFutureTask<V, A>> {
	
	private static final AtomicInteger counter = new AtomicInteger();

	private List<InferenceToken<Object>> inferenceTokens = new ArrayList<InferenceToken<Object>>();
	private int priority;
	private int serno;

	@SuppressWarnings("unchecked")
	public NonBlockingPriorityNotifyingFutureTask(Callable<V> callable, TaskCounter taskCounter, A[] args, int priority) throws InterruptedException {
		super(callable, taskCounter);
		this.priority = priority;
		for (A arg: args) {
			if (arg instanceof InferenceToken<?>) {
				((InferenceToken<?>) arg).taskCreated(priority);
				inferenceTokens .add((InferenceToken<Object>) arg);
			}
		}
		serno = counter.incrementAndGet();
	}
	
	@Override
	public void run() {
		try {
			super.run();
		} finally {
			for (InferenceToken<Object> it: inferenceTokens) {
				it.taskFinished(priority);
			}
		}
	}

	@Override
	public int compareTo(NonBlockingPriorityNotifyingFutureTask<V, A> o) {
		int priorityDifference = o.priority - priority;
		if (priorityDifference!=0) {
			return priorityDifference;
		}
		return serno - o.serno;
	}
	

}
