/*******************************************************************************
 * Copyright (c) 2004, 2007 Mylyn project committers and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/

package org.eclipse.mylyn.internal.context.core;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipOutputStream;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.context.core.ContextCore;
import org.eclipse.mylyn.context.core.IContextStore;
import org.eclipse.mylyn.context.core.IInteractionContext;
import org.eclipse.mylyn.context.core.IInteractionContextScaling;

/**
 * @author Mik Kersten
 * @author Steffen Pingel
 */
public class LocalContextStore implements IContextStore {

	private File contextDirectory;

	private Set<File> contextFiles = null;

	private final InteractionContextExternalizer externalizer = new InteractionContextExternalizer();

	private final IInteractionContextScaling commonContextScaling;

	private final List<IContextStoreListener> listeners = new ArrayList<IContextStoreListener>();

	public LocalContextStore(IInteractionContextScaling commonContextScaling) {
		this.commonContextScaling = commonContextScaling;
	}

	public synchronized void setContextDirectory(File directory) {
		this.contextDirectory = directory;
		for (IContextStoreListener listener : listeners) {
			listener.contextStoreMoved(directory);
		}
//		rootDirectory = new File(TasksUiPlugin.getDefault().getDataDirectory());
//		if (!rootDirectory.exists()) {
//			rootDirectory.mkdir();
//		}
//
//		contextDirectory = new File(rootDirectory, ITasksCoreConstants.CONTEXTS_DIRECTORY);
//		if (!contextDirectory.exists()) {
//			contextDirectory.mkdir();
//		}
	}

	public File getContextDirectory() {
		return contextDirectory;
	}

	/**
	 * @return false if the map could not be read for any reason
	 */
	public IInteractionContext loadContext(String handleIdentifier) {
		return importContext(handleIdentifier, getFileForContext(handleIdentifier));
	}

	public IInteractionContext importContext(String handleIdentifier, File file) {
		return loadContext(handleIdentifier, file, commonContextScaling);
	}

	/**
	 * Creates a file for specified context and activates it
	 */

	public boolean importContext(IInteractionContext context) {
		if (context instanceof InteractionContext) {
			externalizer.writeContextToXml(context, getFileForContext(context.getHandleIdentifier()));
			return true;
		} else {
			return false;
		}
//		contextFiles.add(getFileForContext(context.getHandleIdentifier()));
//		activeContext.getContextMap().put(context.getHandleIdentifier(), context);
//		if (!activationHistorySuppressed) {
//			processActivityMetaContextEvent(new InteractionEvent(InteractionEvent.Kind.COMMAND,
//					IInteractionContextManager.ACTIVITY_STRUCTUREKIND_ACTIVATION, context.getHandleIdentifier(),
//					IInteractionContextManager.ACTIVITY_ORIGINID_WORKBENCH, null,
//					IInteractionContextManager.ACTIVITY_DELTA_ACTIVATED, 1f));
//		}
	}

	public IInteractionContext loadContext(String handleIdentifier, File file, IInteractionContextScaling contextScaling) {
		IInteractionContext loadedContext = externalizer.readContextFromXml(handleIdentifier, file, contextScaling);
		if (loadedContext == null) {
			return new InteractionContext(handleIdentifier, contextScaling);
		} else {
			return loadedContext;
		}
	}

	/**
	 * Only saves if active.
	 */

	public void saveContext(String handleIdentifier) {
		// FIXME this should not reference the context manager
		IInteractionContext context = ContextCore.getContextManager().getActiveContext();
		if (context != null && context.getHandleIdentifier() != null
				&& context.getHandleIdentifier().equals(handleIdentifier)) {
			saveContext(context);
		}
	}

	public void saveContext(IInteractionContext context, String fileName) {
		externalizer.writeContextToXml(context, getFileForContext(fileName));
	}

	public void saveContext(IInteractionContext context) {
		// FIXME this should not reference the context manager
		boolean wasPaused = ContextCore.getContextManager().isContextCapturePaused();
		try {
			// XXX: make this asynchronous by creating a copy

			if (!wasPaused) {
				// FIXME this should not reference the context manager
				ContextCore.getContextManager().setContextCapturePaused(true);
			}

			if (context instanceof InteractionContext) {
				((InteractionContext) context).collapse();
			}
			externalizer.writeContextToXml(context, getFileForContext(context.getHandleIdentifier()));

			if (context.getAllElements().size() == 0) {
				removeFromCache(context);
			} else {
				addToCache(context);
			}
		} catch (Throwable t) {
			StatusHandler.log(new Status(IStatus.ERROR, ContextCorePlugin.PLUGIN_ID, "could not save context", t));
		} finally {
			if (!wasPaused) {
				// FIXME this should not reference the context manager
				ContextCore.getContextManager().setContextCapturePaused(false);
			}
		}
	}

	private boolean addToCache(IInteractionContext context) {
		initCache();
		return contextFiles.add(getFileForContext(context.getHandleIdentifier()));
	}

	private void initCache() {
		if (contextFiles == null) {
			contextFiles = new HashSet<File>();
			File[] files = contextDirectory.listFiles();
			for (File file : files) {
				contextFiles.add(file);
			}
		}
	}

	private boolean removeFromCache(IInteractionContext context) {
		if (contextFiles != null) {
			return contextFiles.remove(getFileForContext(context.getHandleIdentifier()));
		} else {
			return false;
		}
	}

	/**
	 * Consider deleting
	 * 
	 * @param sourceContextFile
	 * @param targetcontextHandle
	 * @return
	 */
	@Deprecated
	public boolean copyContext(File sourceContextFile, String targetcontextHandle) {
		if (sourceContextFile.exists()
				&& sourceContextFile.getName().endsWith(InteractionContextManager.CONTEXT_FILE_EXTENSION)) {
			// FIXME this should not reference the ContextCore
			IInteractionContext context = externalizer.readContextFromXml("temp", sourceContextFile,
					ContextCore.getCommonContextScaling());
			if (context == null) {
				return false;
			}
		}

		File targetContextFile = getFileForContext(targetcontextHandle);
		targetContextFile.delete();
		try {
			// FIXME this implementation is broken: it does not refactor the context handle
			copy(sourceContextFile, targetContextFile);
			contextFiles.add(targetContextFile);
		} catch (IOException e) {
			StatusHandler.log(new Status(IStatus.ERROR, ContextCorePlugin.PLUGIN_ID, "Cold not transfer context: "
					+ targetcontextHandle, e));
			return false;
		}
		return true;
	}

	public IInteractionContext cloneContext(String sourceContextHandle, String destinationContextHandle) {
		IInteractionContext context = importContext(destinationContextHandle, getFileForContext(sourceContextHandle));
		if (context != null) {
//			source.setHandleIdentifier(destinationContextHandle);
			saveContext(context);
		}
		return context;
	}

	public boolean hasContext(String handleIdentifier) {
		Assert.isNotNull(handleIdentifier);
		File file = getFileForContext(handleIdentifier);
		initCache();
		return contextFiles.contains(file);
	}

	public File getFileForContext(String handleIdentifier) {
		String encoded;
		try {
			encoded = URLEncoder.encode(handleIdentifier, InteractionContextManager.CONTEXT_FILENAME_ENCODING);
			File contextDirectory = getContextDirectory();
			File contextFile = new File(contextDirectory, encoded + InteractionContextManager.CONTEXT_FILE_EXTENSION);
			return contextFile;
		} catch (UnsupportedEncodingException e) {
			StatusHandler.log(new Status(IStatus.ERROR, ContextCorePlugin.PLUGIN_ID,
					"Could not determine path for context", e));
		}
		return null;
	}

	public void deleteContext(String handleIdentifier) {
		try {
			File file = getFileForContext(handleIdentifier);
			if (file.exists()) {
				file.delete();
			}

			if (contextFiles != null) {
				contextFiles.remove(getFileForContext(handleIdentifier));
			}
		} catch (SecurityException e) {
			StatusHandler.log(new Status(IStatus.ERROR, ContextCorePlugin.PLUGIN_ID,
					"Could not delete context file, insufficient permissions.", e));
		}
	}

	@Deprecated
	private void copy(File src, File dest) throws IOException {
		InputStream in = new FileInputStream(src);
		try {
			OutputStream out = new FileOutputStream(dest);
			try {
				byte[] buf = new byte[1024];
				int len;
				while ((len = in.read(buf)) == -1) {
					out.write(buf, 0, len);
				}
			} finally {
				out.close();
			}
		} finally {
			in.close();
		}
	}

	/**
	 * Can consider making this API, but it should not expose a zip stream.
	 */
	public void export(String handleIdentifier, ZipOutputStream outputStream) throws IOException {
		IInteractionContext context = loadContext(handleIdentifier);
		externalizer.writeContext(context, outputStream);
	}

	@Deprecated
	public void addListener(IContextStoreListener listener) {
		listeners.add(listener);
	}

	@Deprecated
	public void removeListener(IContextStoreListener listener) {
		listeners.remove(listener);
	}

}
