package org.concord.otrunk.net;

import java.io.File;
import java.io.IOException;
import java.net.CacheRequest;
import java.net.CacheResponse;
import java.net.HttpURLConnection;
import java.net.ResponseCache;
import java.net.URI;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

public class InstallationResponseCache extends ResponseCache
{
	private static final Logger logger =
        Logger.getLogger(InstallationResponseCache.class.getCanonicalName());
	private static File CACHE_DIR;
	static {
		try {
			CACHE_DIR = File.createTempFile("otrunk_cache_", "");
			CACHE_DIR.delete();
			CACHE_DIR.mkdir();
//			CACHE_DIR.deleteOnExit();
			if(!CACHE_DIR.isDirectory()){
				System.err.println("Can't create cache dir");
				CACHE_DIR = null;
			}
			logger.info("Cache dir: " + CACHE_DIR.toString());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			CACHE_DIR = null;
		}
	}
	
	public static void installResponseCache(File cacheDir) {
		CACHE_DIR = cacheDir;
		installResponseCache();
	}
	
	public static void installResponseCache() {
		if (CACHE_DIR != null) {
			ResponseCache.setDefault(new InstallationResponseCache());
		}
	}
	
	public static void clearCache() {
		if (CACHE_DIR != null) {
			delDir(CACHE_DIR);
		}
	}
	
	private static void delDir(File dir) {
		if (dir.isDirectory()) {
			for (File child : dir.listFiles()) {
				if (child.getName().equals(".") || child.getName().equals("..")) {
					continue;
				}
				delDir(child);
				child.delete();
			}
		}
	}
	
	@Override
	public CacheResponse get(URI uri, String rqstMethod, Map<String, List<String>> rqstHeaders)
	    throws IOException
	{
		File localFile = getLocalFile(uri);
		if (!localFile.exists()) {
			logger.info("Cache miss! (" + uri.toString() + ")");
			// the file isn't already in our cache, return null
			return null;
		}
		logger.info("Cache hit! (" + uri.toString() + ")");
		return new InstallationCacheResponse(localFile);
	}

	@Override
	public CacheRequest put(URI uri, URLConnection conn)
	    throws IOException
	{
		// only cache http(s) GET requests
		if (conn instanceof HttpURLConnection) {
			HttpURLConnection httpConn = (HttpURLConnection) conn;
			if (httpConn.getRequestMethod().equals("GET") && isURICachable(uri)) {
				File localFile = getLocalFile(uri);
				logger.info("Caching file: " + uri.toString());
				return new InstallationCacheRequest(localFile, httpConn);
			}
		}
		logger.info("Skipping file: " + uri.toString());
		return null;
	}
	
	/**
	 * Returns the local File corresponding to the given remote URI.
	 */
	public static File getLocalFile(URI remoteUri) {
		int code = remoteUri.hashCode();
		String fileName = Integer.toString(code >= 0 ? code : -code);
		File localFile = new File(CACHE_DIR, fileName);
		// localFile.deleteOnExit();
		return localFile;
	}
	
	private boolean isURICachable(URI uri) {
		// TODO We might want to implement more complex URI filtering here...
		return true;
	}

}

@@ -544,16 +544,57 @@
 HE_DIR;%0A
+%09private static boolean TEMP_DIR = true;%0A
 %09static 
@@ -705,18 +705,16 @@
 kdir();%0A
-//
 %09%09%09CACHE
@@ -1100,16 +1100,36 @@
 cheDir;%0A
+%09%09TEMP_DIR = false;%0A
 %09%09instal
@@ -2892,19 +2892,35 @@
 ame);%0A%09%09
-// 
+if (TEMP_DIR) %7B%0A%09%09%09
 localFil
@@ -2937,16 +2937,20 @@
 Exit();%0A
+%09%09%7D%0A
 %09%09return

Clean up after the session is over, unless a directory is specified, in which cases, don't delete anything.