package org.eclipse.jst.j2ee.internal.common.classpath;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jst.j2ee.internal.common.classpath.J2EEComponentClasspathContainer.LastUpdate;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;

public class J2EEComponentClasspathContainerStore {
	private static final String EAR_LIBRARIES_CACHE = "earLibrariesCache.index"; //$NON-NLS-1$
	private static Map<String, LastUpdate> restoreStateMap;
	private static Map<String, LastUpdate> saveStateMap = new HashMap<String, LastUpdate>();

	static {
		IPath stateLocation = J2EEPlugin.getDefault().getStateLocation();
		java.io.File file = stateLocation.append(EAR_LIBRARIES_CACHE).toFile();
		try {
			if (file.exists()) {
				FileInputStream fIn = null;
				boolean deleteCache = true;
				try {
					fIn = new FileInputStream(file);
					BufferedInputStream bIn = new BufferedInputStream(fIn);
					ObjectInputStream oIn = new ObjectInputStream(bIn);
					restoreStateMap = (HashMap<String, LastUpdate>) oIn.readObject();
					oIn.close();
					
					//it is unfortunate this is necessary, but without iterating over the map
					//and explicitly testing each value, class cast exceptions may occur later
					//best to check them all now and recover
					Iterator<Entry<String, LastUpdate>> iterator = restoreStateMap.entrySet().iterator();
					while(iterator.hasNext()){
						Entry<String, LastUpdate> next = iterator.next();
						String s = next.getKey();
						LastUpdate lu = next.getValue();
						if(s == null || lu == null){
							//may throw ClassCastException
						}
					}
					deleteCache = false;
				} catch (FileNotFoundException e) {
					J2EEPlugin.logError(e);
				} catch (IOException e) {
					J2EEPlugin.logError(e);
				} catch (ClassNotFoundException e) {
					J2EEPlugin.logError(e);
				} catch (ClassCastException e){
					J2EEPlugin.logError(e);
				}
				finally {
					if (fIn != null) {
						try {
							fIn.close();
						} catch (IOException e) {
							J2EEPlugin.logError(e);
						}
					}
					if(deleteCache){
						restoreStateMap = new HashMap<String, LastUpdate>();
						file.delete();
					}
				}
			}
		} catch (Throwable e){
			try{
				J2EEPlugin.logError(e);
				file.delete();
			} catch (Exception e2){
				//eat it
			}
			restoreStateMap = new HashMap<String, LastUpdate>();
		} finally {
			if (restoreStateMap == null) {
				restoreStateMap = new HashMap<String, LastUpdate>();
			}
		}
	}

	private static void persist() {
		synchronized (saveStateMap) {
			IPath stateLocation = J2EEPlugin.getDefault().getStateLocation();
			java.io.File file = stateLocation.append(EAR_LIBRARIES_CACHE).toFile();
			FileOutputStream fOut = null;
			try {
				fOut = new FileOutputStream(file);
				BufferedOutputStream bOut = new BufferedOutputStream(fOut);
				ObjectOutputStream oOut = new ObjectOutputStream(bOut);
				oOut.writeObject(saveStateMap);
				oOut.close();
			} catch (FileNotFoundException e) {
				J2EEPlugin.logError(e);
			} catch (IOException e) {
				J2EEPlugin.logError(e);
			} finally {
				if (fOut != null) {
					try {
						fOut.close();
					} catch (IOException e) {
						J2EEPlugin.logError(e);
					}
				}
			}
		}
	}

	static void flush(String projectName) {
		synchronized (restoreStateMap) {
			restoreStateMap.remove(projectName);
		}
		synchronized (saveStateMap) {
			saveStateMap.remove(projectName);
		}
	}

	static void flushAll() {
		synchronized (restoreStateMap) {
			restoreStateMap.clear();
		}
		synchronized (saveStateMap) {
			saveStateMap.clear();
		}
		IPath stateLocation = J2EEPlugin.getDefault().getStateLocation();
		java.io.File file = stateLocation.append(EAR_LIBRARIES_CACHE).toFile();
		file.delete();
	}

	static LastUpdate getRestoreState(String projectName) {
		LastUpdate lastUpdate = null;
		synchronized (restoreStateMap) {
			lastUpdate = restoreStateMap.get(projectName);
		}
		if (lastUpdate != null) {
			synchronized (saveStateMap) {
				saveStateMap.put(projectName, lastUpdate);
			}
		}
		return lastUpdate;
	}

	private static class PersistJob extends Job {

		public PersistJob() {
			super("Persist EAR Libraries State"); //$NON-NLS-1$
			setSystem(true);
			setRule(null);
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			SafeRunner.run(new ISafeRunnable() {
				public void run() throws Exception {
					persist();
				}

				public void handleException(Throwable exception) {
					J2EEPlugin.logError(exception);
				}
			});
			return Status.OK_STATUS;
		}
	}

	private static int persistDelay = 60000; // 1 minute
	private static PersistJob persistJob = new PersistJob();

	static void saveState(String projectName, LastUpdate lastUpdate) {
		boolean scheduleJob = false;
		synchronized (saveStateMap) {
			LastUpdate previousUpdate = saveStateMap.get(projectName);
			//this check is to avoid I/O if possible
			if(null == previousUpdate || !previousUpdate.equals(lastUpdate)){
				saveStateMap.put(projectName, lastUpdate);
				scheduleJob = true;
			}
		}
		if(scheduleJob){
			synchronized (restoreStateMap) {
				//if it changed, do not load it from the cache again
				restoreStateMap.remove(projectName);
			}
			persistJob.schedule(persistDelay);
		}
	}

}
