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

// Java classes
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.MessageFormat;
import java.util.Calendar;

// Library classes
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
import org.quartz.Trigger;
import org.apache.commons.lang.ClassUtils;

// Framework classes
import gov.va.med.fw.service.AbstractComponent;

// ESR classes

/**
 * Provides detail logging info for a scheduled job in its life cycle
 * 
 * Project: Framework</br> Created on: 3:48:17 PM </br>
 * 
 * @author DNS   LEV
 */
public class ScheduledJobListener extends AbstractComponent implements
		JobListener {

	/**
	 * An instance of jobToBeFiredMessage
	 */
	private String jobToBeFiredMessage = "Job {1}.{0} fired (by trigger {4}.{3}) at: {2, date, HH:mm:ss MM/dd/yyyy}";

	/**
	 * An instance of jobSuccessMessage
	 */
	private String jobSuccessMessage = "Job {1}.{0} execution complete at {2, date, HH:mm:ss MM/dd/yyyy}.  Next fired time is {3}";

	/**
	 * An instance of jobFailedMessage
	 */
	private String jobFailedMessage = "Job {1}.{0} execution failed at {2, date, HH:mm:ss MM/dd/yyyy} due to [{3}].  Next fired time is {4}";

	/**
	 * An instance of jobWasVetoedMessage
	 */
	private String jobWasVetoedMessage = "Job {1}.{0} was vetoed.  It was to be fired (by trigger {4}.{3}) at: {2, date, HH:mm:ss MM/dd/yyyy}";

	/**
	 * An instance of name
	 */
	private String name = null;

	/**
	 * A default constructor
	 */
	public ScheduledJobListener() {
		super();
	}

	/**
	 * @see gov.va.med.fw.service.AbstractComponent#afterPropertiesSet()
	 */
	public void afterPropertiesSet() throws Exception {
		super.afterPropertiesSet();
		this.name = this.getBeanName();
	}

	/**
	 * @see org.quartz.JobListener#getName()
	 */
	public String getName() {
		return this.name;
	}

	/**
	 * @see org.quartz.JobListener#jobToBeExecuted(org.quartz.JobExecutionContext)
	 */
	public void jobToBeExecuted(JobExecutionContext context) {
		if (logger.isInfoEnabled()) {

			Trigger trigger = context.getTrigger();
			Object[] args = { context.getJobDetail().getName(),
							  context.getJobDetail().getGroup(),
							  Calendar.getInstance().getTime(), 
							  trigger.getName(),
							  trigger.getGroup() };
			logger.info( ClassUtils.getShortClassName( getClass() ) + ".jobToBeExecuted" );
			logger.info(MessageFormat.format(this.jobToBeFiredMessage, args));
		}
	}

	/**
	 * @see org.quartz.JobListener#jobExecutionVetoed(org.quartz.JobExecutionContext)
	 */
	public void jobExecutionVetoed(JobExecutionContext context) {
		if (logger.isInfoEnabled()) {

			Trigger trigger = context.getTrigger();
			Object[] args = { context.getJobDetail().getName(),
							  context.getJobDetail().getGroup(),
							  Calendar.getInstance().getTime(), 
							  trigger.getName(),
							  trigger.getGroup() };

			logger.info( ClassUtils.getShortClassName( getClass() ) + ".jobExecutionVetoed" );
			logger.info(MessageFormat.format(this.jobWasVetoedMessage, args));
		}
	}

	/**
	 * @see org.quartz.JobListener#jobWasExecuted(org.quartz.JobExecutionContext,
	 *      org.quartz.JobExecutionException)
	 */
	public void jobWasExecuted(JobExecutionContext context,JobExecutionException exception) {

		Trigger trigger = context.getTrigger();
		if (exception != null) {
			if (logger.isInfoEnabled()) {
				logger.info( ClassUtils.getShortClassName( getClass() ) + ".jobWasExecuted" );
				Object[] args = new Object[] { context.getJobDetail().getName(),
											   context.getJobDetail().getGroup(),
											   Calendar.getInstance().getTime(), 
											   exception.getMessage(),
											   trigger.getNextFireTime() };

				logger.info( MessageFormat.format( this.jobFailedMessage, args ) );

				StringWriter errorWriter = new StringWriter();
				PrintWriter printWriter = new PrintWriter(errorWriter);
				exception.printStackTrace(printWriter);
				printWriter.flush();
				logger.info("Detail Stack Trace: " + errorWriter.toString());
			}
		} 
		else {
			if (logger.isInfoEnabled()) {
				logger.info( ClassUtils.getShortClassName( getClass() ) + ".jobWasExecuted" );
				Object[] args = new Object[] { context.getJobDetail().getName(),
											   context.getJobDetail().getGroup(),
											   Calendar.getInstance().getTime(), 
											   trigger.getNextFireTime() };
				logger.info( MessageFormat.format( this.jobSuccessMessage, args ) );
			}
		}
	}
}