package com.ym.mec.task.core;

import java.util.Map;
import java.util.Map.Entry;

import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.ym.mec.task.core.TaskException;
import com.ym.mec.task.service.TaskService;

@Component
public class LocalJobFactory implements JobFactory, ApplicationContextAware {

	private ApplicationContext applicationContext;

	@Autowired
	private TaskService taskService;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	@Override
	public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
		Job job = null;
		JobDetail jobDetail = bundle.getJobDetail();
		Class<? extends Job> jobClass = jobDetail.getJobClass();
		Map<String, ? extends Job> jobMap = applicationContext.getBeansOfType(jobClass);
		if (jobMap == null || jobMap.size() == 0) {
			try {
				job = jobClass.newInstance();
			} catch (Exception e) {
				throw new TaskException("Problem instantiating class '" + jobClass.getName() + "'", e);
			}
		} else if (jobMap.size() > 1) {
			throw new TaskException("Get multiple instance from spring application context by type[{" + jobClass.getName() + "}]");
		} else {
			for (Entry<String, ? extends Job> entry : jobMap.entrySet()) {
				job = entry.getValue();
				break;
			}
		}
		return new DelegatingJob(job, taskService);
	}

	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

}
