/*
 * Copyright 2002-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/
package integration.anyframe.services.scheduling;

import integration.anyframe.services.AbstractTest;

import org.quartz.Scheduler;
import org.quartz.impl.SchedulerRepository;
import org.springframework.scheduling.quartz.SchedulerAccessorBean;

public class SchedulingServiceTest extends AbstractTest {
	/**
	 * 테스트 수행을 위한 main
	 */
	public static void main(String[] args) throws Exception {

		SchedulingServiceTest schedulingTest = new SchedulingServiceTest();

		// 1. initialize context
		schedulingTest.setup();
		// 2. test
		schedulingTest.testSimpleTrigger01();
		schedulingTest.testSimpleTrigger02();
		schedulingTest.testCronTrigger();
		schedulingTest.testJobSchedulingData();
		schedulingTest.testSchedulerAccessorBean();
		
		// 3. close context
		schedulingTest.teardown();
		
		System.out.println("Successful!!!!!!");

	}
	
	/**
	 * SimpleTrigger에 등록된 JobDetailBean의 Stateless QuatzJob을 수행하고 결과 값을 확인한다.
	 */		
	public void testSimpleTrigger01() throws Exception {
		Thread.sleep(1000*5);
						
		int result = SimpleQuartzJobBean.getResult();	
		System.out.println("main >> result of Stateless QuatzJobBean bean :"+	result);
		
		if ( result!=7){
			throw new Exception(" Scheduling Service failed : result is " + result );
		}		
	}
	
	/**
	 * SimpleTrigger에 등록된 JobDetailBean의 Stateful QuatzJob을 수행하고 결과 값을 확인한다.
	 */		
	public void testSimpleTrigger02() throws Exception {
		Thread.sleep(1000*5);
						
		int result = StatefulQuartzJobBean.getResult();
		System.out.println("main >> result of Stateful QuatzJobBean bean :"+	result);
		
		if ( result!=10){
			throw new Exception(" Scheduling Service failed : result is " + result );
		}		
	}
	

	/**
	 * CronTrigger에 등록된 POJO Job을 수행하고 결과 값을 확인한다.
	 */		
	public void testCronTrigger() throws Exception {
		Thread.sleep(1000*50);
		SimplePOJOJobBean simplePOJOJobBean = ( SimplePOJOJobBean )context.getBean("simplePOJOJobBean");
		
		int result = simplePOJOJobBean.getCount();
		System.out.println("main >> result of simplePOJOJobBean  :"+ result);
		
		if ( result <= 0 ){
			throw new Exception(" Scheduling Service failed ");
		}
	}	
	
	/**
	 * Quartz의 job definition XML file(job_scheduling_data_1_5 XSD 적용)을 통해 
	 * Job과 Trigger를 설정한 후 Stateless QuatzJob을 수행하고 결과 값을 확인한다.
	 */		
	public void testJobSchedulingData() throws Exception {
		Thread.sleep(1000*10);

		int result = SimpleJobBean.getResult();	
		System.out.println("main >> result of JobSchedulingData Stateless QuatzJob :"+	result);
		
		if ( result!=7){
			throw new Exception(" Scheduling Service failed : result is " + result );
		}	
	}	
	
	/**
	 * SchedulerAccessorBean을 이용하여 등록된 Scheduler에 접근하여 Scheduler name, TriggerListener 등의 정보를
	 * 확인한다.
	 */		
	public void testSchedulerAccessorBean() throws Exception {
		Thread.sleep(1000*10);
		
		// basically doesn't expose Scheduler In Repository
		assertNull(SchedulerRepository.getInstance().lookup("scheduler01"));
		// if you set exposeSchedulerInRepository property to "true", you can get Scheduler from Global SchedulerRepository
		Scheduler scheduler02 = SchedulerRepository.getInstance().lookup("scheduler02");
		assertSameScheduler(scheduler02, context.getBean("schedulerFactoryBeanWithJobSchedulingData"));		
		assertSameTriggerListenersSize(scheduler02.getGlobalTriggerListeners().size(), 1);
		
		// get Scheduler through SchedulerAccessorBean
		SchedulerAccessorBean schedulerAccessorBean = (SchedulerAccessorBean) context.getBean("schedulerAccessorBean");
		assertSameScheduler(schedulerAccessorBean.getScheduler().getSchedulerName(),"scheduler02");
	}		
	
	@Override
	protected String[] getConfigLocations() {
		return new String[]{"classpath*:/common/applicationContext-*.xml",
				"classpath*:/services/scheduling/applicationContext-*.xml"};
	}
	
	protected void assertSameScheduler(Object actual, Object expected) throws Exception {
		if(!expected.equals(actual)){
			throw new Exception(" Scheduling Service failed : two Scheduler instance should be same, expected=" + expected + ", actual="+actual );
		}
	}
	
	protected void assertSameTriggerListenersSize(int actual, int expected) throws Exception {
		if(expected != actual){
			throw new Exception(" Scheduling Service failed : triggerListeners size should be " + expected );
		}
	}	
	
	protected void assertNull(Object actual) throws Exception {
		if(actual != null){
			throw new Exception(" Scheduling Service failed : this Scheduler instance should be null, actual="+actual );
		}
	}	
}


