/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/
// Package
package gov.va.med.fw.scheduling;

// Java classes
import java.util.Map;
import java.util.Date;

// Library classes
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.scheduling.quartz.JobDetailBean;

// Framework classes
import gov.va.med.fw.util.AbstractContextAwareTestCase;

// ESR classes

/**
 * Provides test cases for a scheduler service
 *
 * Project: Framework</br>
 * Created on: 1:10:04 PM </br>
 *
 * @author DNS   LEV
 */
public class SchedulerServiceTest extends AbstractContextAwareTestCase {

	private SchedulingService schedulingService = null;
	
	/**
	 * A default constructor
	 */
	public SchedulerServiceTest() {
		super();
	}
	
	public void testSchedulingService() throws Exception {
		
		// Test 1: Schedule an immediate job to send out an e-mail
		final String jobName = "immediateJob";
		final String jobGroup = "immediateJobGroup";
		scheduleImmediateTask( jobName, jobGroup );
		
		// Test 2: Schedule a future job to send out an e-mail
		//
		// This is similar to start a clock for 2 minutes and a clock
		// expires, a task is executed.  In this is case, it is a task
		// to send out an e-mail
		final String triggerName = "futureJobTrigger";
		final String triggerGroup = "futureJobTriggerGroup";
		Date clock = TriggerUtils.getNextGivenSecondDate( new Date(), 30 );
		scheduleFutureTask( clock, triggerName, triggerGroup );
		
		// Test 3: Illustrate how to query for a job that
		//
		// Get a scheduling service
		SchedulingService scheduler = this.getSchedulingService();
		Trigger trigger = scheduler.getTrigger( triggerName, triggerGroup );
		
		if(trigger != null) {
			logger.info( "This is a trigger description: " + trigger.getDescription() );
		}
	}
	
	/**
	 * @throws Exception
	 */
	private void scheduleImmediateTask( String name, String group ) throws Exception {
		
		// Get a scheduling service
		SchedulingService scheduler = this.getSchedulingService();
		
		// Scenario 1: Illustrates how to pass dynamic data 
		// In this case, we pass a message template and a message
		SimpleMailMessage tpl = (SimpleMailMessage)this.applicationContext.getBean( "messageTemplate" );
		String msg = "This is a test message from a scheduled service for immediate trigger";
		
		// Get a job detail to populate it with data neccessary for the job to run 
		JobDetailBean jobDetail = (JobDetailBean)this.applicationContext.getBean( "dynamicEmailJob" );
		jobDetail.setName( name );
		jobDetail.setGroup( group );

		Map data = jobDetail.getJobDataMap();
		data.put( "methodArguments", new Object[]{ msg, tpl } );
		
		// Now schedule a job to run right away
		Trigger trigger = (Trigger)this.applicationContext.getBean( "immediateTrigger" );
		trigger.setJobGroup( group );
		trigger.setJobName( name );
		
		jobDetail.setName( name );
		jobDetail.setGroup( group );
		scheduler.schedule( jobDetail, trigger );
		
		// Scenario 2: Illustrate how to pass all static data 
		// This is as good as it gets !!!!!!
		
		// Get a job detail to fully populate with static data  
		jobDetail = (JobDetailBean)this.applicationContext.getBean( "staticEmailJob" );
		jobDetail.setGroup( group );
		jobDetail.setName( name + "WithStaticData" );
		
		// Get a trogger to trigger a job
		trigger = (Trigger)this.applicationContext.getBean( "immediateTrigger" );
		trigger.setJobName( name + "WithStaticData" );
		trigger.setJobGroup( group );
		trigger.setName( name + "WithStaticData" );

		scheduler.schedule( jobDetail, trigger );
		
	}

	/**
	 * @param clock
	 * @param name
	 * @param group
	 * @throws Exception
	 */
	private void scheduleFutureTask( Date clock, String name, String group ) throws Exception {
	
		// Get a scheduling service
		SchedulingService scheduler = this.getSchedulingService();
		
		// Get a preconfigured trigger to set its clock and name
		Trigger trigger = (Trigger)this.applicationContext.getBean( "futureTrigger" );
		trigger.setStartTime( clock );
		trigger.setJobName( name );
		trigger.setJobGroup( group );
		
		// Put some description here so we can retrieve it later.  Simply for testing
		trigger.setDescription( "Trigger Name: " + trigger.getName() );

		// Get a job detail to fully populate with static data  
		JobDetailBean jobDetail = (JobDetailBean)this.applicationContext.getBean( "staticEmailJob" );
		jobDetail.setName( name );
		jobDetail.setGroup( group );
		scheduler.schedule( jobDetail, trigger );
	}

	/**
	 * @return Returns the schedulingService.
	 */
	public SchedulingService getSchedulingService() {
		return schedulingService;
	}

	/**
	 * @param schedulingService The schedulingService to set.
	 */
	public void setSchedulingService(SchedulingService schedulingService) {
		this.schedulingService = schedulingService;
	}
}