package gov.va.med.fw.scheduling;

import java.util.Date;
import java.util.List;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;

import gov.va.med.fw.service.trigger.TriggerEvent;

public interface SchedulingService {
	public static final String IMMEDIATE_TRIGGER_NAME = "immediate";
	public static final String FUTURE_TRIGGER_NAME = "future";
	
   public abstract boolean isClustered();

   public abstract void setIsClustered(boolean flag);

   /**
    * @return Returns the scheduler.
    */
   public abstract Scheduler getScheduler();

   /**
    * @param scheduler The scheduler to set.
    */
   public abstract void setScheduler(Scheduler scheduler);

   /**
    * @return Returns the futureTriggerKey.
    */
   public abstract String getFutureTriggerKey();

   /**
    * @param futureTriggerKey The futureTriggerKey to set.
    */
   public abstract void setFutureTriggerKey(String futureTriggerKey);

   /**
    * @return Returns the immediateTriggerKey.
    */
   public abstract String getImmediateTriggerKey();

   /**
    * @param immediateTriggerKey The immediateTriggerKey to set.
    */
   public abstract void setImmediateTriggerKey(String immediateTriggerKey);

   /**
    * @param jobDetail the job detail
    * @param trigger the trigger
    *
    * @return the date the job was scheduled
    * @throws SchedulerException if a problem was encountered
    */
   public abstract Date schedule(JobDetail jobDetail, Trigger trigger)
         throws SchedulerException;

   /**
    * Schedule a job for execution with an hourly increment delay (eg, trigger in 4 hours).
    *
    * @param jobDetail JobDetail to use (does not already have to be registered with scheduler).
    * @param contextDataForThisTrigger Dynamic data for this trigger. This is data that can be preconfigured (eg,
    * EntityKey for the target AbstractEntity).
    * @param numberOfHoursDelayed Number of hours from current time to trigger. This can be fractional (eg, 0.25 means
    * fire in 15 minutes)
    * @param triggerName If passed in, this must be considered unique (with group) by the caller. Trigger will be given
    * this name (instead of default name).
    * @param triggerGroup If passed in, this must be considered unique (with name) by the caller. Trigger will be given
    * this group (instead of default group).
    *
    * @return the date the job was scheduled.
    * @throws SchedulerException if a problem was encountered
    */
   public abstract Date schedule(JobDetail jobDetail, List contextDataForThisTrigger,
         double numberOfHoursDelayed, String triggerName, String triggerGroup)
         throws SchedulerException;

   /**
    * @param trigger the trigger
    *
    * @return the date the job was scheduled
    * @throws SchedulerException if a problem was encountered
    */
   public abstract Date schedule(Trigger trigger) throws SchedulerException;

   /**
    * @param invocationContext the invocation context
    *
    * @throws SchedulerException if a problem was encountered
    */
   public abstract void fireJobWithImmediateTrigger(
         ScheduledProcessInvocationContext invocationContext) throws SchedulerException;

   
   /**
    * @param job the job
    *
    * @throws SchedulerException if a problem was encountered
    */
   public abstract void fireJobWithImmediateTrigger(JobDetail job) throws SchedulerException;

   /**
    * @param event the trigger event
    *
    * @throws SchedulerException if a problem was encountered
    */
   public abstract void fireJobWithImmediateTrigger(TriggerEvent event) throws SchedulerException;

   /**
    * @param triggerName the trigger name
    * @param groupName the group name
    *
    * @return True if the job was successfully unscheduled or false if not.
    *         False will be returned if a job doesn't exist with the specified triggerName and groupName.
    * @throws SchedulerException if a problem was encountered
    */
   public abstract boolean unschedule(String triggerName, String groupName)
         throws SchedulerException;

   /**
    * @param triggerName the trigger name.
    * @param groupName the group name
    * @param newTrigger the new trigger
    *
    * @return the date the job has been rescheduled
    * @throws SchedulerException if a problem was encountered
    */
   public abstract Date reschedule(String triggerName, String groupName,
         Trigger newTrigger) throws SchedulerException;

   /**
    * Request the interruption of all currently executing instances of the identified Job, which must be an implementor of
    * the InterruptableJob interface. This method delegates interrupt request to org.quartz.Scheduler.interrupt method.
    * <p/>
    * If more than one instance of the identified job is currently executing, the InterruptableJob#interrupt() method will
    * be called on each instance. However, there is a limitation that in the case that interrupt() on one instances throws
    * an exception, all remaining instances (that have not yet been interrupted) will not have their interrupt() method
    * called. If you wish to interrupt a specific instance of a job (when more than one is executing) you can do so by
    * calling getCurrentlyExecutingJobs() to obtain a handle to the job instance, and then invoke interrupt() on it
    * yourself.
    *
    * @param jobName the job name
    * @param groupName the group name
    *
    * @return true if at least one instance of the identified job was found and interrupted
    * @throws SchedulerException if a problem was encountered
    * @see org.quartz.Scheduler#interrupt(String,String)
    */
   public abstract boolean interrupt(String jobName, String groupName)
         throws SchedulerException;

   /**
    * Request the interruption of all currently executing instances of the identified Job, which must be an implementor of
    * the InterruptableJob interface. This method delegates interrupt request to interrupt method that takes job name and
    * group name as an argument.
    *
    * @param jobDetail - a job detail
    *
    * @return true if at least one instance of the identified job was found and interrupted
    * @throws SchedulerException if a problem was encountered
    * @see org.quartz.Scheduler#interrupt(String,String)
    */
   public abstract boolean interrupt(JobDetail jobDetail) throws SchedulerException;

   /**
    * @return the list of job group names
    * @throws SchedulerException if a problem was encountered
    */
   public abstract String[] getJobGroupNames() throws SchedulerException;

   /**
    * @param groupName the group name
    *
    * @return the jogb names
    * @throws SchedulerException if a problem was encountered
    */
   public abstract String[] getJobNames(String groupName) throws SchedulerException;

   /**
    * @return the group names
    * @throws SchedulerException if a problem was encountered
    */
   public abstract String[] getTriggerGroupNames() throws SchedulerException;

   /**
    * @param groupName the group name
    *
    * @return the trigger names
    * @throws SchedulerException if a problem was encountered
    */
   public abstract String[] getTriggerNames(String groupName) throws SchedulerException;

   /**
    * @param jobName the job name
    * @param jobGroup the group name
    *
    * @return the job detail information
    * @throws SchedulerException if a problem was encountered
    */
   public abstract JobDetail getJobDetail(String jobName, String jobGroup)
         throws SchedulerException;

   /**
    * @param triggerName the trigger name
    * @param triggerGroup the group name
    *
    * @return the trigger
    * @throws SchedulerException if a problem was encountered
    */
   public abstract Trigger getTrigger(String triggerName, String triggerGroup)
         throws SchedulerException;

   public abstract TriggerStatus getTriggerStatus(String triggerName, String triggerGroup)
         throws SchedulerException;

   public abstract void pauseJob(String jobName, String jobGroup)
         throws SchedulerException;

   public abstract void pauseTriggerGroup(String triggerGroup)
   	throws SchedulerException;
   
   public abstract void pauseAllJobs() throws SchedulerException;

   public abstract void resumeJob(String jobName, String jobGroup)
         throws SchedulerException;

   public abstract void resumeTriggerGroup(String triggerGroup)
   	throws SchedulerException;
   
   public abstract void resumeAllJobs() throws SchedulerException;

}