/**
 * JobSchedulerTest.java
 * Created on Jun 10, 2008
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.watchpoint.pmm.job.unitTests;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import junit.framework.TestCase;

import com.tandbergtv.watchpoint.pmm.entities.Context;
import com.tandbergtv.watchpoint.pmm.entities.Job;
import com.tandbergtv.watchpoint.pmm.entities.JobParameter;
import com.tandbergtv.watchpoint.pmm.entities.PartnerContext;
import com.tandbergtv.watchpoint.pmm.entities.Rule;
import com.tandbergtv.watchpoint.pmm.entities.RuleParameter;
import com.tandbergtv.watchpoint.pmm.entities.RuleParameterDataType;
import com.tandbergtv.watchpoint.pmm.entities.RuleType;
import com.tandbergtv.watchpoint.pmm.entities.RuleTypeParameter;
import com.tandbergtv.watchpoint.pmm.job.scheduling.IJobScheduleManager;
import com.tandbergtv.watchpoint.pmm.job.scheduling.JobSchedulerActivator;
import com.tandbergtv.watchpoint.pmm.job.scheduling.QuartzScheduleManager;
import com.tandbergtv.workflow.core.ProcessPriority;

/**
 * @author spuranik
 *
 */
public class JobSchedulerTest extends TestCase {

	private JobSchedulerActivator activator;
	private static int TIME_PARAMETER_INDEX = 3;

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#setUp()
	 */
	@Override
	protected void setUp() throws Exception {

		activator = new JobSchedulerActivator();
		activator.start();

		super.setUp();
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#tearDown()
	 */
	@Override
	protected void tearDown() throws Exception {

		activator.stop();
		super.tearDown();
	}

	public void _testEveryNweeksScheduling() {
		Job job = new Job();

		job.setId(1);

		Context context = new PartnerContext();
		context.setId(1L);
		job.setContext(context);

		job.setName("job 1");

		List<JobParameter> jobParams = new ArrayList<JobParameter>();
		JobParameter p1 = new JobParameter();
		p1.setId(1);
		p1.setJob(job);
		p1.setName("Some var");
		p1.setValue("Some value");
		jobParams.add(p1);
		job.setJobParams(jobParams);

		job.setPriority(ProcessPriority.NORMAL);

		job.setTemplateName("Test Template1");

		Rule rule = new Rule();
		List<RuleParameter> ruleParams = new ArrayList<RuleParameter>();
		RuleParameter rp1 = new RuleParameter();
		rp1.setOrder(1);		
		rp1.setValue("2");
		ruleParams.add(rp1);
		RuleParameter rp2 = new RuleParameter();
		rp2.setOrder(2);
		rp2.setValue("1:48 pm");
		ruleParams.add(rp2);		

		rule.setStartDate(new Date());
		/*Calendar c = Calendar.getInstance();
		c.setTime(new Date());
		c.add(Calendar.DATE, 1);
		rule.setEndDate(c.getTime());*/
		rule.setCallbackClass("com.tandbergtv.watchpoint.pmm.job.unitTests.MockCallback");
		rule.setTimeClass("com.tandbergtv.watchpoint.pmm.job.timers.EveryNWeeks");

		RuleType type = new RuleType();
		
		ArrayList<RuleTypeParameter> rtParams = new ArrayList<RuleTypeParameter>();
		type.setName("EveryNWeeks");
		RuleTypeParameter rtp1 = new RuleTypeParameter();
		rtp1.setOrder(1);
		rtp1.setType(RuleParameterDataType.INTEGER);
		rtParams.add(rtp1);
		RuleTypeParameter rtp2 = new RuleTypeParameter();
		rtp2.setOrder(2);
		rtp2.setType(RuleParameterDataType.TIME);
		rtParams.add(rtp2);
		
		type.setParams(rtParams);

		rule.setType(type);
		rule.setParams(ruleParams);

		job.setRule(rule);

		IJobScheduleManager qmgr = QuartzScheduleManager.getInstance();
		qmgr.addSchedule(job);

		// trying to add another job with least effort! i could have created another job object in a loop
		// and used. But not going thru that hastle.
		// job.setId(2L);
		// qmgr.addSchedule(job);

		String[] jobNames = ((QuartzScheduleManager) qmgr).getAllScheduledJobNames();
		for (int i = 0; i < jobNames.length; i++) {
			System.out.println("Job[" + i + "]: " + jobNames[i]);
		}

		try {
			Thread.sleep(20000);
		} catch (InterruptedException e) {
			System.out.println("Error: " + e.toString());
		}

		System.out.println("Updating job now");
		job.getRule().getParams().get(TIME_PARAMETER_INDEX).setValue("6:15 pm");
		qmgr.updateSchedule(job);
		
		try {
			Thread.sleep(50000);
		} catch (InterruptedException e) {
			System.out.println("Error: " + e.toString());
		}
		
		int jobcount = ((QuartzScheduleManager) qmgr).getExecutedJobCount();
		System.out.println(jobcount + " jobs were executed.");

		qmgr.deleteSchedules(job);

		jobNames = ((QuartzScheduleManager) qmgr).getAllScheduledJobNames();
		if (jobNames.length == 0)
			System.out.println("No jobs found");
		else {
			for (int i = 0; i < jobNames.length; i++) {
				System.out.println("Job[" + i + "]: " + jobNames[i]);
			}
		}
	}
	
	public void _testDailyScheduling() {
		Job job = new Job();

		job.setId(1);
		
		Context context = new PartnerContext();
		context.setId(1L);
		job.setContext(context);

		job.setName("job 1");

		List<JobParameter> jobParams = new ArrayList<JobParameter>();
		JobParameter p1 = new JobParameter();
		p1.setId(1);
		p1.setJob(job);
		p1.setName("Some var");
		p1.setValue("Some value");
		jobParams.add(p1);
		job.setJobParams(jobParams);

		job.setPriority(ProcessPriority.NORMAL);

		job.setTemplateName("Test Template1");

		Rule rule = new Rule();
		Calendar c = Calendar.getInstance();
		c.setTime(new Date());
		c.add(Calendar.DATE, 2);
		rule.setEndDate(c.getTime());
		
		List<RuleParameter> ruleParams = new ArrayList<RuleParameter>();
		RuleParameter rp1 = new RuleParameter();
		rp1.setOrder(4);		
		rp1.setValue("3:17 pm");
		ruleParams.add(rp1);

		rule.setStartDate(new Date());
		rule.setCallbackClass("com.tandbergtv.watchpoint.pmm.job.unitTests.MockCallback");
		rule.setTimeClass("com.tandbergtv.watchpoint.pmm.job.timers.Daily");

		RuleType type = new RuleType();
		
		ArrayList<RuleTypeParameter> rtParams = new ArrayList<RuleTypeParameter>();
		type.setName("NDaysFromMetadata");
		RuleTypeParameter rtp1 = new RuleTypeParameter();
		rtp1.setOrder(4);
		rtp1.setType(RuleParameterDataType.TIME);
		rtParams.add(rtp1);		
		type.setParams(rtParams);

		rule.setType(type);
		rule.setParams(ruleParams);

		job.setRule(rule);

		IJobScheduleManager qmgr = QuartzScheduleManager.getInstance();
		qmgr.addSchedule(job);

		System.out.println("Done");		
	}

	public void _testOnDateScheduling() {
		Job job = new Job();

		job.setId(1);

		Context context = new PartnerContext();
		context.setId(1L);
		job.setContext(context);

		job.setName("job 1");

		List<JobParameter> jobParams = new ArrayList<JobParameter>();
		JobParameter p1 = new JobParameter();
		p1.setId(1);
		p1.setJob(job);
		p1.setName("Some var");
		p1.setValue("Some value");
		jobParams.add(p1);
		job.setJobParams(jobParams);

		job.setPriority(ProcessPriority.NORMAL);

		job.setTemplateName("Test Template1");

		Rule rule = new Rule();
		List<RuleParameter> ruleParams = new ArrayList<RuleParameter>();
		RuleParameter rp1 = new RuleParameter();
		rp1.setOrder(1);		
		rp1.setValue("2008-07-11");
		ruleParams.add(rp1);
		RuleParameter rp2 = new RuleParameter();
		rp2.setValue("3:24 pm");
		rp2.setOrder(2);		
		ruleParams.add(rp2);		

		rule.setStartDate(new Date());
		rule.setCallbackClass("com.tandbergtv.watchpoint.pmm.job.unitTests.MockCallback");
		rule.setTimeClass("com.tandbergtv.watchpoint.pmm.job.timers.OnDate");

		RuleType type = new RuleType();
		
		ArrayList<RuleTypeParameter> rtParams = new ArrayList<RuleTypeParameter>();
		type.setName("OnDate");
		RuleTypeParameter rtp1 = new RuleTypeParameter();
		rtp1.setOrder(1);
		rtp1.setType(RuleParameterDataType.DATE);
		rtParams.add(rtp1);
		RuleTypeParameter rtp2 = new RuleTypeParameter();
		rtp2.setOrder(2);
		rtp2.setType(RuleParameterDataType.TIME);
		rtParams.add(rtp2);		
		
		type.setParams(rtParams);

		rule.setType(type);
		rule.setParams(ruleParams);

		job.setRule(rule);

		IJobScheduleManager qmgr = QuartzScheduleManager.getInstance();
		qmgr.addSchedule(job);

		System.out.println("Done");		
	}
	
	public void _testDateTime()
	{
		Date today = new Date();
		System.out.println("Date: " + today.toString());
		
		Calendar c = Calendar.getInstance();
		c.setTime(today);
		String time = "3:24 pm";
		
		try {
			SimpleDateFormat sf = new SimpleDateFormat("h:mm a");
			sf.setLenient(false);
			Date dt = sf.parse(time);
			
			Calendar tc = Calendar.getInstance();
			tc.setTime(dt);
			System.out.println("Time: " + tc.getTime().toString());
			
			c.set(Calendar.HOUR_OF_DAY, tc.get(Calendar.HOUR_OF_DAY));
			c.set(Calendar.MINUTE, tc.get(Calendar.MINUTE));			
			c.set(Calendar.SECOND, 0);
			
			System.out.println("DateTime: " + c.getTime().toString());
			
		} catch (ParseException e) {
			System.out.println("Error: " + e.toString()); 
		}
	}

	public void testOnDayNweeksScheduling() {
		Job job = new Job();

		job.setId(1);

		Context context = new PartnerContext();
		context.setId(1L);
		job.setContext(context);

		job.setName("job 1");

		List<JobParameter> jobParams = new ArrayList<JobParameter>();
		JobParameter p1 = new JobParameter();
		p1.setId(1);
		p1.setJob(job);
		p1.setName("Some var");
		p1.setValue("Some value");
		jobParams.add(p1);
		job.setJobParams(jobParams);

		job.setPriority(ProcessPriority.NORMAL);

		job.setTemplateName("Test Template1");

		Rule rule = new Rule();
		List<RuleParameter> ruleParams = new ArrayList<RuleParameter>();
		RuleParameter rp1 = new RuleParameter();
		rp1.setOrder(1);		
		rp1.setValue("THURSDAY");		
		RuleParameter rp2 = new RuleParameter();
		rp2.setOrder(2);
		rp2.setValue("2");		
		RuleParameter rp3 = new RuleParameter();
		rp3.setOrder(3);
		rp3.setValue("3:26 pm");

		ruleParams.add(rp1);
		ruleParams.add(rp2);
		ruleParams.add(rp3);

		rule.setStartDate(new Date());
		/* Calendar c = Calendar.getInstance();
		c.setTime(new Date());
		c.add(Calendar.DATE, 17);
		rule.setEndDate(c.getTime()); */
		rule.setCallbackClass("com.tandbergtv.watchpoint.pmm.job.unitTests.MockCallback");
		rule.setTimeClass("com.tandbergtv.watchpoint.pmm.job.timers.OnDayEveryNWeeks");

		RuleType type = new RuleType();
		
		ArrayList<RuleTypeParameter> rtParams = new ArrayList<RuleTypeParameter>();
		type.setName("OnDayEveryNWeeks");
		RuleTypeParameter rtp1 = new RuleTypeParameter();
		rtp1.setOrder(1);
		rtp1.setType(RuleParameterDataType.DAY);
		rtParams.add(rtp1);
		RuleTypeParameter rtp2 = new RuleTypeParameter();
		rtp2.setOrder(2);
		rtp2.setType(RuleParameterDataType.INTEGER);
		rtParams.add(rtp2);
		RuleTypeParameter rtp3 = new RuleTypeParameter();
		rtp3.setOrder(3);
		rtp3.setType(RuleParameterDataType.TIME);
		rtParams.add(rtp3);		
		
		type.setParams(rtParams);

		rule.setType(type);
		rule.setParams(ruleParams);

		job.setRule(rule);

		IJobScheduleManager qmgr = QuartzScheduleManager.getInstance();
		qmgr.addSchedule(job);

		String[] jobNames = ((QuartzScheduleManager) qmgr).getAllScheduledJobNames();
		for (int i = 0; i < jobNames.length; i++) {
			System.out.println("Job[" + i + "]: " + jobNames[i]);
		}

		try {
			Thread.sleep(20000);
		} catch (InterruptedException e) {
			System.out.println("Error: " + e.toString());
		}
	}

}

