/* Copyright (c) 2011 Peter Troshin
 *  
 *  JAva Bioinformatics Analysis Web Services (JABAWS) @version: 2.0     
 * 
 *  This library is free software; you can redistribute it and/or modify it under the terms of the
 *  Apache License version 2 as published by the Apache Software Foundation
 * 
 *  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Apache 
 *  License for more details.
 * 
 *  A copy of the license is in apache_license.txt. It is also available here:
 * @see: http://www.apache.org/licenses/LICENSE-2.0.txt
 * 
 * Any republication or derived work distributed in source code form
 * must include this copyright and license notice.
 */
package compbio.ws.server;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.log4j.Logger;

import compbio.stat.collector.DirCleaner;
import compbio.stat.collector.StatDB;
import compbio.engine.conf.PropertyHelperManager;
import compbio.engine.local.ExecutableWrapper;
import compbio.engine.local.LocalExecutorService;
import compbio.engine.client.EngineUtil;
import compbio.util.PropertyHelper;

/**
 * Two tasks:
 * 1. Switch off engines if JABAWS web application is un-deployed, or web server is shutdown
 * 2. delete old job directories
 * 
 * @author Peter Troshin
 * @author Alexander Sherstnev
 * @version 2.0
 */
public class MainManager implements ServletContextListener {

	private final Logger log = Logger.getLogger(MainManager.class);
	static PropertyHelper ph = PropertyHelperManager.getPropertyHelper();
	
	private ScheduledFuture<?> localcl;
	private ScheduledFuture<?> clustercl;
	private ScheduledExecutorService executor;
	
	@Override
	public void contextDestroyed(ServletContextEvent ignored) {
		// stop cleaning job directories
		try {
			if (null != localcl) {
				localcl.cancel(true);
			}
			if (null != clustercl) {
				clustercl.cancel(true);
			}
			executor.shutdown();
			executor.awaitTermination(3, TimeUnit.SECONDS);
		} catch (InterruptedException e) {
			log.warn(e.getMessage(), e);
		}

			// Shutdown local and cluster engines
			log.info("JABAWS context is destroyed. Shutting down engines...");
			LocalExecutorService.shutDown();
			log.info("Local engine is shutdown OK");
			ExecutableWrapper.shutdownService();
			log.info("Individual executables stream engine is shutdown OK");
			StatDB.shutdownDBServer();
	}

	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		log.info("Initializing directory cleaners");
		executor = Executors.newScheduledThreadPool(2);

		// configure cluster cleaner
		String clusterWorkDir = getClusterJobDir();
		int clusterDirLifespan = PropertyHelperManager.getIntProperty(ph.getProperty("cluster.jobdir.maxlifespan"));
		int clusterCleaningRate = PropertyHelperManager.getIntProperty(ph.getProperty("cluster.jobdir.cleaning.frequency"));
		boolean cleanClasterDir = PropertyHelperManager.getBooleanProperty(ph.getProperty("cluster.stat.collector.enable"));
		
		if (0 < clusterDirLifespan && cleanClasterDir) {
			DirCleaner clusterDirCleaner = new DirCleaner(clusterWorkDir, clusterDirLifespan);
			clustercl = executor.scheduleAtFixedRate(clusterDirCleaner, 1, clusterCleaningRate, TimeUnit.MINUTES);
			log.info("Cleaning local job directory every " + clusterCleaningRate + " minutes");
		} else {
			log.info("Cluster job directory cleaner is disabled. ");
		}

		// configure local cleaner
		String localWorkDir = EngineUtil.convertToAbsolute(getLocalJobDir());
		int localDirLiveSpan = PropertyHelperManager.getIntProperty(ph.getProperty("local.jobdir.maxlifespan"));
		int localCleaningRate = PropertyHelperManager.getIntProperty(ph.getProperty("local.jobdir.cleaning.frequency"));
		boolean cleanLocalDir = PropertyHelperManager.getBooleanProperty(ph.getProperty("local.stat.collector.enable"));

		if (0 < localDirLiveSpan && cleanLocalDir) {
			DirCleaner localDirCleaner = new DirCleaner(localWorkDir, localDirLiveSpan);
			localcl = executor.scheduleAtFixedRate(localDirCleaner, 1, localCleaningRate, TimeUnit.MINUTES);
			log.info("Cleaning local job directory every " + localCleaningRate + " minutes");
		} else {
			log.info("Local job directory cleaner is disabled. ");
		}
	}

	static String getClusterJobDir() {
		String ln = ph.getProperty("cluster.tmp.directory");
		if (null != ln ) {
		  ln = ln.trim();
		}
		return ln;
	}

	static String getLocalJobDir() {
		String ln = ph.getProperty("local.tmp.directory");
		if (null != ln ) {
			ln = ln.trim();
		}
		return ln;
	}
}
