package skyview.survey;

import java.io.File;
import skyview.executive.Settings;
import static skyview.survey.CachingImageFactory.DFT_CACHE;

/**
 * This class handles interactions with the file cache.
 * @author tmcglynn
 */
public class Cacher {
    
    
    static private java.util.regex.Pattern comma = java.util.regex.Pattern.compile(",");    
    
    /** If we are divvying the cache by surveys, find the appropriate name
     *  for the current survey subdirectory.
     * @return The escaped name of the survey.
     */
    public String getSurveySubdir() {
        String subdir = null;
	String[]   dirs = Settings.getArray("shortname");
	if (dirs.length == 0) {
            return null;
	} else {
            subdir = dirs[0];
	    subdir = subdir.replaceAll("[^a-zA-Z0-9\\-\\_\\+\\.]", "_");
	}
        return subdir;        
    }
    
    /** See if there is a file in the cache that is of the approprite
     *  name.
     * @param file
     * @return  The full path to the file. 
     */
    public String getCachedFileName(String file) {
        
    	String   cacheString  = Settings.get("cache", DFT_CACHE);
	String[] caches       = comma.split(cacheString);
	
	// First try the caches without the survey
	// name appended
        
	for (String cache: caches) {
	    String test = cache+file;
	    if (new java.io.File(test).exists()) {
                return test;
	    }
	}
        
        boolean  appendSurvey = Settings.has("SaveBySurvey");
	String   subdir       =  null;
        
	if (appendSurvey) {
            subdir = getSurveySubdir();
            if (subdir == null) {
                appendSurvey = false;
            }
	}	
	
	// Now if the user has asked for the cache to
	// be split, try inside...
	if (appendSurvey) {
	    for (String cache: caches) {
	        String test = cache+subdir+File.separatorChar+file;
	        if (new java.io.File(test).exists()) {
                    return test;
	        }
	    }
	}
        return null;
    }
    
    /** Find the name of the write cache directory and if necessary create it */
    public String getWriteCache() {
	String[] caches = Settings.getArray("Cache");
	if (caches.length == 0) {
	    caches = new String[]{CachingImageFactory.DFT_CACHE};
	}
	
	String cache = caches[0];
        if (Settings.has("SaveBySurvey")) {
	    cache += getSurveySubdir() + File.separatorChar;
        }	    
	
	File dir = new File(cache);
	if (!dir.exists()) {
	    try {
		dir.mkdirs();
	    } catch (Exception e) {
		System.err.println("Error creating cache:"+caches[0]);
		throw new Error("Error: Unable to create cache directory");
	    }
	}
        return cache;
    }

    /** Read a URL into the cache and return the full path to the cached file.
     * 
     */
    public String cacheRemoteURL(String url, String cacheFile) throws Exception {
        
        int offset = cacheFile.lastIndexOf(File.separatorChar);
        String cache = getWriteCache();
        if (offset >= 0) {
            // We have subdirectories involved so we need to make sure they exist.
            String dir = cache + cacheFile.substring(0, offset);
            File dirf = new File(dir);
            if (!dirf.isDirectory()) {
                if (!dirf.mkdirs()) {
                    throw new Exception("Unable to create directory: "+dir+" within cache");
                }
            }            
        }
        
        String xfile  = cache+cacheFile;
        String tfile = xfile + new java.util.Date().getTime();
        skyview.survey.Util.getURL(url, tfile);
        
        File f = new File(tfile);
        f.renameTo(new File(xfile));
        if (Settings.get("purgecache") != null) {
            Settings.add("_cachedfile", xfile);
        }
        return xfile;
    }
    
    
    public String getFile(String url, String file) throws Exception {
        String cacheFile = getCachedFileName(file);
        if (cacheFile == null) {
            return cacheRemoteURL(url, file);
        } else {
            return cacheFile;
        }
    }
}
