/* Copyright (c) 2013 Alexander Sherstnev
 *  
 *  JAva Bioinformatics Analysis Web Services (JABAWS) @version: 2.1     
 * 
 *  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.stat.collector;

import java.io.File;
import java.io.FileFilter;
import java.util.Date;

import org.apache.log4j.Logger;

import compbio.engine.Cleaner;
import compbio.engine.client.PathValidator;
import compbio.stat.collector.JobStat;

/**
 * Number of runs of each WS = number of folders with name
 * 
 * Number of successful runs = all runs with no result file
 * 
 * Per period of time = limit per file creating time Runtime (avg/max) =
 * 
 * started time - finished time
 * 
 * Task & result size = result.size
 * 
 * Abandoned runs - not collected runs
 * 
 * Cancelled runs - cancelled
 * 
 * Cluster vs local runs
 * 
 * Reasons for failure = look in the err out?
 * 
 * Metadata required:
 * 
 * work directory for local and cluster tasks = from Helper or cmd parameter. WS
 * names - enumeration. Status file names and content.
 * 
 * @author pvtroshin
 * 
 */
public class DirCleaner implements Runnable {

	static final int UNDEFINED = -1;

	private static final Logger log = Logger.getLogger(DirCleaner.class);

	final private File workDirectory;
	final private int LifeSpanInHours;

	/**
	 * 
	 * @param workDirectory
	 * @param timeOutInHours
	 */
	public DirCleaner(String workDirectory, int LifeSpanInHours) {
		log.info("Starting cleaning for directory: " + workDirectory);
		log.info("Maximum allowed directory life span (h): " + LifeSpanInHours);
		if (!PathValidator.isValidDirectory(workDirectory)) {
			throw new IllegalArgumentException("workDirectory '" + workDirectory + "' does not exist!");
		}
		this.workDirectory = new File(workDirectory);
		this.LifeSpanInHours = LifeSpanInHours;
	}

	boolean hasCompleted(JobDirectory jd) {
		JobStat jstat = jd.getJobStat();
		if (jstat.hasResult() || jstat.getIsCancelled() || jstat.getIsFinished()) {
			return true;
		}
		return false;
	}

	boolean livesOverLifeSpan(JobDirectory jd) {
		long LifeTime = (System.currentTimeMillis() - jd.jobdir.lastModified()) / (1000 * 60 * 60);
		log.debug("lifetime = " + LifeTime + ", lifespan = " + LifeSpanInHours);
		return LifeTime > LifeSpanInHours;
	}

	static FileFilter directories = new FileFilter() {
		@Override
		public boolean accept(File pathname) {
			return pathname.isDirectory() && !pathname.getName().startsWith(".");
		}
	};
	
	// TODO test!
	void doCleaning() {
		File[] dirs = workDirectory.listFiles(directories);
		for (File dir : dirs) {
			// Do not look at dirs with unfinished jobs
			JobDirectory jd = new JobDirectory(dir);
			Date d = new Date (dir.lastModified());
			log.debug("Directory " + dir.getName() + " has timestamp: " + d);
			// TODO. removed hasCompeted. Maybe it needs to be restored...
			// if (hasCompleted(jd) && livesOverLifeSpan(jd)) {
			if (livesOverLifeSpan(jd)) {
				if (Cleaner.deleteDirectory(workDirectory.getAbsolutePath() + File.separator + dir.getName())) {
					log.error("Directory " + dir.getName() + " failed to deleted...");
				} else {
					log.debug("Directory " + dir.getName() + " is deleted");
				}
			} else {
				log.debug("Directory " + dir.getName() + " is too new and kept");
			}
		}
	}
	@Override
	public void run() {
		log.info("Started cleaning job directory at " + new Date());
		log.info("For directory: " + workDirectory.getAbsolutePath());
		doCleaning();
		log.info("Finished cleaning job directory at " + new Date());
	}
}
