/**
 * JobManager.java
 * Created on May 15, 2008
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.watchpoint.pmm.job;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.tandbergtv.cms.portal.util.transaction.Transactional;
import com.tandbergtv.watchpoint.pmm.dao.hibernate.HibernateContext;
import com.tandbergtv.watchpoint.pmm.entities.Job;
import com.tandbergtv.watchpoint.pmm.entities.JobParameterConstants;
import com.tandbergtv.watchpoint.pmm.entities.RuleType;
import com.tandbergtv.watchpoint.pmm.job.dao.IJobHDAO;
import com.tandbergtv.watchpoint.pmm.job.dao.IJobRuleTypeDAO;
import com.tandbergtv.watchpoint.pmm.job.dao.JobHDAO;
import com.tandbergtv.watchpoint.pmm.job.dao.JobRuleTypeHDAO;
import com.tandbergtv.watchpoint.pmm.job.scheduling.IJobScheduleManager;
import com.tandbergtv.workflow.core.service.ServiceRegistry;

/**
 * This class manages all job related tasks.
 * @author spuranik
 */
public class JobManager implements IJobManager {

	private static IJobManager instance;

	/**
	 * Default ctor
	 */
	private JobManager() {
	}

	/**
	 * @return singleton object of job manager
	 */
	public static synchronized IJobManager getInstance() {
		if (instance == null) {
			instance = new JobManager();
		}
		return instance;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.tandbergtv.watchpoint.pmm.job.IJobManager#createJob(com.tandbergtv.watchpoint.pmm.entities.Job)
	 */
	@Transactional
	public void createJob(Job job) {
		// add the job to the database
		Session session = HibernateContext.getContext().getCurrentSession();
		IJobHDAO jobDAO = new JobHDAO(session);
		jobDAO.create(job);

		// schedule the job in the scheduling engine
		IJobScheduleManager scheduleManager = ServiceRegistry.getDefault()
				.lookup(IJobScheduleManager.class);
		scheduleManager.addSchedule(job);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.tandbergtv.watchpoint.pmm.job.IJobManager#deleteJob(long)
	 */
	@Transactional
	public synchronized void deleteJob(long jobId) {
		// get the job in the first session. this will be used for removing
		// the schedule
		Session session = HibernateContext.getContext().getCurrentSession();
		IJobHDAO jobDAO = new JobHDAO(session);
		Job j = jobDAO.findByKey(jobId);
		jobDAO.delete(jobId);

		// remove schedule for the job from the scheduling engine
		IJobScheduleManager scheduleManager = ServiceRegistry.getDefault()
				.lookup(IJobScheduleManager.class);
		scheduleManager.deleteSchedules(j);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.tandbergtv.watchpoint.pmm.job.IJobManager#getAllJobs(long)
	 */
	@Transactional
	public synchronized List<Job> getAllJobs(long contextId) {
		List<Job> jobs = new ArrayList<Job>();
		Session session = HibernateContext.getContext().getCurrentSession();
		IJobHDAO jobDAO = new JobHDAO(session);
		Criteria criteria = session.createCriteria(Job.class).add(
				Restrictions.eq("context.id", contextId));
		jobs = jobDAO.findByCriteria(criteria);
		return jobs;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.tandbergtv.watchpoint.pmm.job.IJobManager#getRuleType(java.lang.String)
	 */
	@Transactional
	public RuleType getRuleType(String name) {
		RuleType ruleType = new RuleType();
		Session session = HibernateContext.getContext().getCurrentSession();
		IJobRuleTypeDAO ruleTypeDAO = new JobRuleTypeHDAO(session);
		Criteria criteria = session.createCriteria(RuleType.class).add(
				Restrictions.eq("name", name));
		ruleType = ruleTypeDAO.findUniqueByCriteria(criteria);
		return ruleType;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.tandbergtv.watchpoint.pmm.job.IJobManager#getAllRuleTypes()
	 */
	@Transactional
	public List<RuleType> getAllRuleTypes() {
		List<RuleType> ruleTypes = new ArrayList<RuleType>();
		Session session = HibernateContext.getContext().getCurrentSession();
		IJobRuleTypeDAO ruleTypeDAO = new JobRuleTypeHDAO(session);
		ruleTypes = ruleTypeDAO.findAll();
		return ruleTypes;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.tandbergtv.watchpoint.pmm.job.IJobManager#getRuleType(org.hibernate.Criteria)
	 */
	@Transactional
	public List<RuleType> getRuleTypes(boolean isAssociatedWithTitles) {
		List<RuleType> ruleTypes = new ArrayList<RuleType>();
		Session session = HibernateContext.getContext().getCurrentSession();
		IJobRuleTypeDAO ruleTypeDAO = new JobRuleTypeHDAO(session);
		Criteria criteria = session.createCriteria(RuleType.class).add(
				Restrictions.eq("titlesAssociated", isAssociatedWithTitles));
		ruleTypes = ruleTypeDAO.findByCriteria(criteria);
		return ruleTypes;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.tandbergtv.watchpoint.pmm.job.IJobManager#getJob(long)
	 */
	@Transactional
	public synchronized Job getJob(long jobId) {
		Session session = HibernateContext.getContext().getCurrentSession();
		IJobHDAO jobDAO = new JobHDAO(session);
		return jobDAO.findByKey(jobId);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.tandbergtv.watchpoint.pmm.job.IJobManager#updateJob(com.tandbergtv.watchpoint.pmm.entities.Job)
	 */
	@Transactional
	public synchronized void updateJob(Job job) {
		Session session = HibernateContext.getContext().getCurrentSession();
		IJobHDAO jobDAO = new JobHDAO(session);
		jobDAO.update(job);

		// update the schedule for this job in the scheduling engine
		IJobScheduleManager scheduleManager = ServiceRegistry.getDefault()
				.lookup(IJobScheduleManager.class);
		scheduleManager.updateSchedule(job);
	}

	@Transactional	
	public List<Job> getAllJobs(String ruleSetId) {
		Session session = HibernateContext.getContext().getCurrentSession();
		String query = "select distinct j"
				+ " from com.tandbergtv.watchpoint.pmm.entities.Job j, "
				+ " com.tandbergtv.watchpoint.pmm.entities.JobParameter jp"
				+ " where jp.job.id = j.id" + " and jp.name = '"
				+ JobParameterConstants.RULESET_ID + "' and jp.value = '"
				+ ruleSetId + "'";
		return session.createQuery(query).list();
	}	
}
