package com.hammurapi.common.concurrent;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.RunnableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class DelegatingRunnableFuture<V> implements RunnableFuture<V> {
	
	private Future<V> target;

	private Runnable command;

	private Callable<V> task;
	
	public DelegatingRunnableFuture(Runnable command, V value) {
		this.command = command;
		this.value = value;
	}
	
	public Runnable getCommand() {
		return command;
	}
	
	public DelegatingRunnableFuture(Callable<V> task) {
		this.task = task;
	}
	
	public Callable<V> getTask() {
		return task;
	}
	
	public boolean cancel(boolean mayInterruptIfRunning) {
		return target.cancel(mayInterruptIfRunning);
	}

	public boolean isCancelled() {
		return target.isCancelled();
	}

	public boolean isDone() {
		return target.isDone();
	}

	public V get() throws InterruptedException, ExecutionException {
		return target.get();
	}

	public V get(long timeout, TimeUnit unit) throws InterruptedException,
			ExecutionException, TimeoutException {
		return target.get(timeout, unit);
	}

	@Override
	public void run() {
		if (target instanceof Runnable) {
			((Runnable) target).run();
		} else {
			throw new UnsupportedOperationException("Target is not runnable");
		}
	}
	
	public void setTarget(Future<V> target) {
		this.target = target;
	}	
	
	private V value;
	
	public V getValue() {
		return value;
	}
}
