/**
 * IProcessManagerService.java
 * Created Jan 9, 2007
 * Copyright (C) Tandberg Television 2007
 */
package com.tandbergtv.workflow.driver.service;

import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.Future;

import org.jbpm.graph.def.ProcessDefinition;

import com.tandbergtv.workflow.core.CustomToken;
import com.tandbergtv.workflow.core.ProcessPriority;
import com.tandbergtv.workflow.core.WorkflowProcess;
import com.tandbergtv.workflow.core.event.IColleague;
import com.tandbergtv.workflow.core.service.Service;
import com.tandbergtv.workflow.driver.DriverException;

/**
 * This interface represents a process lifecycle manager. It provides a facility to create, run,
 * pause and terminate processes.
 * 
 * Calls are executed asynchronously, the caller must wait on the Future that is returned
 * after making the call if the synchronous result is desired. The only exceptions are calls that
 * are cheap or easier to execute synchronously, i.e. on the invoking thread. 
 * 
 * @author Sahil Verma
 */
public interface IProcessManagerService extends Service, IColleague {

	/**
	 * Creates a new process from the specified template using input parameter values and with the
	 * default priority. Note that the process hasn't started yet, it will enter the start node 
	 * and wait there. To invoke the process execution, call start().
	 * 
	 * @param template the template that will be instantiated
	 * @param parameters the input parameters
	 * @return the root token of the newly created process
	 * @throws DriverException
	 */
	CustomToken create(ProcessDefinition template, Map<String, Object> parameters) throws DriverException;
	
	/**
	 * Creates a new process from the specified template using input parameter values and with the
	 * specified priority. Note that the process hasn't started yet, it will enter the start node 
	 * and wait there. To invoke the process execution, call start().
	 * 
	 * @param template the template that will be instantiated
	 * @param priority the initial priority of the new process
	 * @param parameters the input parameters
	 * @return the root token of the newly created process
	 * @throws DriverException
	 */
	CustomToken create(ProcessDefinition template, ProcessPriority priority, Map<String, Object> parameters) 
		throws DriverException;

	/**
	 * Creates a child process of the specified token from the specified template using input
	 * parameter values
	 * 
	 * @param token the parent token
	 * @param template the template that will be used to instantiate the process
	 * @param parameters the input parameters
	 * @return the root of the newly created process
	 * @throws DriverException
	 */
	CustomToken create(CustomToken token, ProcessDefinition template, Map<String, Object> parameters)
		throws DriverException;
	
	/**
	 * Starts execution of the specified token
	 * 
	 * @param token
	 * @throws DriverException
	 */
	Future<CustomToken> start(CustomToken token) throws DriverException;
	
	/**
	 * Suspends execution of the specified token. If the token is executing a long running
	 * task, it will be paused when the task completes. Until then it is not possible to 
	 * change the state of the token.
	 * 
	 * @param token
	 */
	Future<CustomToken> pause(CustomToken token);
	
	/**
	 * Suspends execution of the specified tokens.
	 * 
	 * @param tokens the tokens to be paused
	 * @return a list of futures that can be waited upon, or else an empty list
	 */
	Collection<Future<CustomToken>> pause(Collection<CustomToken> tokens);

	/**
	 * Resumes a process that was previously paused or had failed. This either resume()s a 
	 * suspend()ed process or signal()s the process if it was in a wait state.
	 * 
	 * @param token
	 * @throws DriverException
	 */
	Future<CustomToken> resume(CustomToken token) throws DriverException;
	
	/**
	 * Creates and starts a new process from the same template and using the same variables as the 
	 * specified process.
	 * 
	 * @param id the id of the process that will be cloned and started 
	 * @throws DriverException
	 */
	Future<CustomToken> restart(Serializable id) throws DriverException;
	
	/**
	 * Runs a process that was previously queued
	 * 
	 * @param token
	 * @return
	 */
	Future<CustomToken> dequeue(CustomToken token);

	/**
	 * Forcibly cancels a single process execution path.
	 * 
	 * @param token
	 * @throws DriverException
	 */
	Future<CustomToken> cancel(CustomToken token);
	
	/**
	 * Forcibly cancels all the specified execution paths
	 * 
	 * @param tokens the tokens to be cancelled
	 * @return a list of futures that can be waited upon, or else an empty list
	 */
	Collection<Future<CustomToken>> cancel(Collection<CustomToken> tokens);
	
	/**
	 * Logically deletes a process. The entity is not removed from the datasource, it merely
	 * disappears from the UI. 
	 * 
	 * @param process
	 * @throws DriverException
	 */
	Future<CustomToken> delete(WorkflowProcess process) throws DriverException;
	
	/**
	 * Pauses all active processes
	 * 
	 * @throws DriverException
	 */
	Future<Void> pause() throws DriverException;
	
	/**
	 * Resumes all processes that are paused
	 * 
	 * @throws DriverException
	 */
	Future<Void> resume() throws DriverException;
	
	/**
	 * Sets the priority of the specified process
	 * 
	 * @param process the process
	 * @param priority the new priority
	 */
	void setPriority(WorkflowProcess process, ProcessPriority priority);
}
