/**
 * VersionService.java
 * Created Sep 18, 2007
 * Copyright (c) Tandberg Television 2007
 */
package com.tandbergtv.workflow.driver.template;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ResourceBundle;

import org.apache.log4j.Logger;

import com.tandbergtv.workflow.core.WorkflowTemplate;
import com.tandbergtv.workflow.core.service.ServiceRegistry;
import com.tandbergtv.workflow.core.service.thread.ISchedulerService;
import com.tandbergtv.workflow.driver.service.IProcessSearchService;
import com.tandbergtv.workflow.driver.service.ITemplateLoaderService;

/**
 * Default implementation of the template version service
 * 
 * @author Sahil Verma
 */
public class ArchivalService implements IArchivalService {

	private ISchedulerService<Void> scheduler;
	
	private static final String SERVICE_NAME = "template-version";
	
	private static final long ONE_MINUTE_MILLIS = 60 * 1000L;
	
	private static final long ONE_HOUR_MILLIS = 60 * ONE_MINUTE_MILLIS;
	
	private static final long ONE_DAY_MILLIS = 24 * ONE_HOUR_MILLIS;
	
	private long period;
	
	private long delay;
	
	private long runs;
	
	private static final Logger logger = Logger.getLogger(ArchivalService.class);
	
	/**
	 * Creates a {@link ArchivalService}
	 */
	public ArchivalService(ISchedulerService<Void> scheduler) {
		this.scheduler = scheduler;
		ResourceBundle bundle = 
			ResourceBundle.getBundle(this.getClass().getPackage().getName() + ".service");
		DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
		String timeofday = bundle.getString("version.service.timeofday");
		
		try {
			long time = formatter.parse(timeofday).getTime();
			long now = formatter.parse(formatter.format(new Date())).getTime();
			
			delay = time - now;
			
			if (delay < 0)
				delay += ONE_DAY_MILLIS;
			
			logger.debug(time / ONE_MINUTE_MILLIS + ", " + now / ONE_MINUTE_MILLIS);
		} catch (ParseException e) {
			delay = 0;
		}
		
		try {
			this.period = Long.parseLong(bundle.getString("version.service.period")) * ONE_MINUTE_MILLIS;
		} catch (Exception e) {
			this.period = ONE_DAY_MILLIS;
		}
		
		logger.info("Starting at " + timeofday + ", period = " + period / ONE_HOUR_MILLIS + " hours");
	}

	/* (non-Javadoc)
	 * @see com.tandbergtv.workflow.core.service.Service#getServiceName()
	 */
	public String getServiceName() {
		return SERVICE_NAME;
	}

	/* (non-Javadoc)
	 * @see com.tandbergtv.workflow.core.service.ServiceLifecycle#start()
	 */
	public void start() {
		scheduler.schedule(new Runnable() {
			public void run() {
				ServiceRegistry registry = ServiceRegistry.getDefault();
				ITemplateLoaderService loader = registry.lookup(ITemplateLoaderService.class);
				IProcessSearchService search = registry.lookup(IProcessSearchService.class);
				
				new VersionBasedArchivalStrategy(loader, search).archive();
				runs++;
			}
		}, this.delay, this.period);
	}

	/* (non-Javadoc)
	 * @see com.tandbergtv.workflow.core.service.ServiceLifecycle#stop()
	 */
	public void stop() {
	}

	/* (non-Javadoc)
	 * @see com.tandbergtv.workflow.driver.template.IArchivalService#run(com.tandbergtv.workflow.core.WorkflowTemplate)
	 */
	public void run(final WorkflowTemplate template) {
		ServiceRegistry registry = ServiceRegistry.getDefault();
		ITemplateLoaderService loader = registry.lookup(ITemplateLoaderService.class);
		IProcessSearchService search = registry.lookup(IProcessSearchService.class);

		new VersionBasedArchivalStrategy(loader, search).archive(template);
	}
}
