/*******************************************************************************
 * Copyright (c) 2011, 2012 Tasktop Technologies.
 * 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
 *
 * Contributors:
 *     Tasktop Technologies - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.internal.context.tasks.ui;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URLDecoder;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.mylyn.commons.core.CommonListenerList;
import org.eclipse.mylyn.commons.core.CommonListenerList.Notifier;
import org.eclipse.mylyn.commons.core.CoreUtil;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.commons.core.storage.CommonStore;
import org.eclipse.mylyn.commons.core.storage.ICommonStorable;
import org.eclipse.mylyn.context.core.ContextCore;
import org.eclipse.mylyn.context.core.IInteractionContext;
import org.eclipse.mylyn.internal.context.core.ContextCorePlugin;
import org.eclipse.mylyn.internal.context.core.InteractionContext;
import org.eclipse.mylyn.internal.context.core.InteractionContextManager;
import org.eclipse.mylyn.internal.context.tasks.ui.TaskContextStoreEvent.Kind;
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
import org.eclipse.mylyn.internal.tasks.core.RepositoryTaskHandleUtil;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.monitor.core.InteractionEvent;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.context.AbstractTaskContextStore;
import org.eclipse.mylyn.tasks.ui.TasksUi;
import org.eclipse.osgi.util.NLS;

/**
 * @author Steffen Pingel
 */
public class TaskContextStore extends AbstractTaskContextStore {

	private static final String FOLDER_DATA = "data"; //$NON-NLS-1$

	private final CommonListenerList<TaskContextStoreListener> listeners;

	private File directory;

	private CommonStore taskStore;

	private final ContextStatePersistenceHandler stateHandler;

	public TaskContextStore() {
		this.listeners = new CommonListenerList<TaskContextStoreListener>(TasksUiPlugin.ID_PLUGIN);
		this.stateHandler = new ContextStatePersistenceHandler();
	}

	public void addListener(TaskContextStoreListener listener) {
		listeners.add(listener);
	}

	@Override
	public void clearContext(ITask task) {
		ContextCorePlugin.getContextManager().deleteContext(task.getHandleIdentifier());

		stateHandler.clear(task);

		final TaskContextStoreEvent event = new TaskContextStoreEvent(Kind.CLEAR, task);
		listeners.notify(new Notifier<TaskContextStoreListener>() {
			@Override
			public void run(TaskContextStoreListener listener) throws Exception {
				listener.taskContextChanged(event);
			}
		});
	}

	@Override
	public IAdaptable copyContext(ITask sourceTask, ITask targetTask) {
		IInteractionContext result = copyContextInternal(sourceTask, targetTask);

		stateHandler.copy(sourceTask, targetTask);

		final TaskContextStoreEvent event = new TaskContextStoreEvent(Kind.COPY, sourceTask, targetTask);
		listeners.notify(new Notifier<TaskContextStoreListener>() {
			@Override
			public void run(TaskContextStoreListener listener) throws Exception {
				listener.taskContextChanged(event);
			}
		});

		return asAdaptable(result);
	}

	@Override
	public void deleteContext(ITask task) {
		ICommonStorable storable = getStorable(task);
		try {
			storable.deleteAll();
		} catch (CoreException e) {
			StatusHandler.log(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN,
					"Unexpected error while deleting context state", e)); //$NON-NLS-1$
		} finally {
			storable.release();
		}

		ContextCorePlugin.getContextManager().deleteContext(task.getHandleIdentifier());
		stateHandler.clear(task);

		final TaskContextStoreEvent event = new TaskContextStoreEvent(Kind.DELETE, task);
		listeners.notify(new Notifier<TaskContextStoreListener>() {
			@Override
			public void run(TaskContextStoreListener listener) throws Exception {
				listener.taskContextChanged(event);
			}
		});
	}

	@Override
	public File getFileForContext(ITask task) {
		return ContextCorePlugin.getContextStore().getFileForContext(task.getHandleIdentifier());
	}

	public ICommonStorable getStorable(ITask task) {
		return getTaskStore().get(getPath(task));
	}

	@Override
	public boolean hasContext(ITask task) {
		return ContextCore.getContextStore().hasContext(task.getHandleIdentifier());
	}

	@Override
	public void mergeContext(ITask sourceTask, ITask targetTask) {
		ContextCorePlugin.getContextStore().merge(sourceTask.getHandleIdentifier(), targetTask.getHandleIdentifier());

		stateHandler.merge(sourceTask, targetTask);

		final TaskContextStoreEvent event = new TaskContextStoreEvent(Kind.MERGE, sourceTask, targetTask);
		listeners.notify(new Notifier<TaskContextStoreListener>() {
			@Override
			public void run(TaskContextStoreListener listener) throws Exception {
				listener.taskContextChanged(event);
			}
		});
	}

	@Override
	public IAdaptable moveContext(ITask sourceTask, ITask targetTask) {
		final IInteractionContext result = copyContextInternal(sourceTask, targetTask);

		// move task activity
		ChangeActivityHandleOperation operation = new ChangeActivityHandleOperation(sourceTask.getHandleIdentifier(),
				targetTask.getHandleIdentifier());
		try {
			operation.run(new NullProgressMonitor());
		} catch (InvocationTargetException e) {
			StatusHandler.log(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN,
					"Failed to migrate activity to new task", e)); //$NON-NLS-1$
		} catch (InterruptedException e) {
			// ignore
		}

		try {
			getTaskStore().move(getPath(sourceTask), getPath(targetTask));
		} catch (CoreException e) {
			StatusHandler.log(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN,
					"Failed to migrate context state to new task", e)); //$NON-NLS-1$
		}

		final TaskContextStoreEvent event = new TaskContextStoreEvent(Kind.MOVE, sourceTask, targetTask);
		listeners.notify(new Notifier<TaskContextStoreListener>() {
			@Override
			public void run(TaskContextStoreListener listener) throws Exception {
				listener.taskContextChanged(event);
			}
		});

		return asAdaptable(result);
	}

	@Override
	public void refactorRepositoryUrl(TaskRepository repository, String oldRepositoryUrl, String newRepositoryUrl) {
		refactorMetaContextHandles(oldRepositoryUrl, newRepositoryUrl);
		refactorContextFileNames(oldRepositoryUrl, newRepositoryUrl);
		if (repository != null) {
			refactorRepositoryLocation(repository, oldRepositoryUrl, newRepositoryUrl);
		}
	}

	public void removeListener(TaskContextStoreListener listener) {
		listeners.remove(listener);
	}

	@Override
	public void saveActiveContext() {
		ContextCorePlugin.getContextStore().saveActiveContext();

		ITask task = TasksUi.getTaskActivityManager().getActiveTask();
		if (task != null) {
			stateHandler.saved(task);

			final TaskContextStoreEvent event = new TaskContextStoreEvent(Kind.SAVE, task);
			listeners.notify(new Notifier<TaskContextStoreListener>() {
				@Override
				public void run(TaskContextStoreListener listener) throws Exception {
					listener.taskContextChanged(event);
				}
			});
		}
	}

	@Override
	public synchronized void setDirectory(File directory) {
		this.directory = directory;
		if (taskStore != null) {
			taskStore.setLocation(directory);
		}

		File contextDirectory = new File(directory.getParent(), ITasksCoreConstants.CONTEXTS_DIRECTORY);
		if (!contextDirectory.exists()) {
			contextDirectory.mkdirs();
		}
		ContextCorePlugin.getContextStore().setContextDirectory(contextDirectory);
	}

	private IAdaptable asAdaptable(final IInteractionContext result) {
		return new IAdaptable() {
			public Object getAdapter(Class adapter) {
				if (adapter == IInteractionContext.class) {
					return result;
				}
				return null;
			}
		};
	}

	private IInteractionContext copyContextInternal(ITask sourceTask, ITask targetTask) {
		ContextCorePlugin.getContextStore().saveActiveContext();
		final IInteractionContext result = ContextCore.getContextStore().cloneContext(sourceTask.getHandleIdentifier(),
				targetTask.getHandleIdentifier());
		return result;
	}

	private IPath getPath(ITask task) {
		IPath path = new Path(""); //$NON-NLS-1$
		path = path.append(task.getConnectorKind() + "-" + CoreUtil.asFileName(task.getRepositoryUrl())); //$NON-NLS-1$
		path = path.append(FOLDER_DATA);
		path = path.append(CoreUtil.asFileName(task.getTaskId()));
		return path;
	}

	private synchronized CommonStore getTaskStore() {
		if (taskStore == null) {
			taskStore = new CommonStore(directory);
		}
		return taskStore;
	}

	@SuppressWarnings("restriction")
	private void refactorContextFileNames(String oldUrl, String newUrl) {
		File dataDir = new File(TasksUiPlugin.getDefault().getDataDirectory(), ITasksCoreConstants.CONTEXTS_DIRECTORY);
		if (dataDir.exists() && dataDir.isDirectory()) {
			File[] files = dataDir.listFiles();
			if (files != null) {
				for (File file : dataDir.listFiles()) {
					int dotIndex = file.getName().lastIndexOf(".xml"); //$NON-NLS-1$
					if (dotIndex != -1) {
						String storedHandle;
						try {
							storedHandle = URLDecoder.decode(file.getName().substring(0, dotIndex),
									InteractionContextManager.CONTEXT_FILENAME_ENCODING);
							int delimIndex = storedHandle.lastIndexOf(RepositoryTaskHandleUtil.HANDLE_DELIM);
							if (delimIndex != -1) {
								String storedUrl = storedHandle.substring(0, delimIndex);
								if (oldUrl.equals(storedUrl)) {
									String id = RepositoryTaskHandleUtil.getTaskId(storedHandle);
									String newHandle = RepositoryTaskHandleUtil.getHandle(newUrl, id);
									File newFile = ContextCorePlugin.getContextStore().getFileForContext(newHandle);
									file.renameTo(newFile);
								}
							}
						} catch (Exception e) {
							StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
									"Could not move context file: " + file.getName(), e)); //$NON-NLS-1$
						}
					}
				}
			}
		}
	}

	@SuppressWarnings("restriction")
	private void refactorMetaContextHandles(String oldRepositoryUrl, String newRepositoryUrl) {
		InteractionContext metaContext = ContextCorePlugin.getContextManager().getActivityMetaContext();
		ContextCorePlugin.getContextManager().resetActivityMetaContext();
		InteractionContext newMetaContext = ContextCorePlugin.getContextManager().getActivityMetaContext();
		for (InteractionEvent event : metaContext.getInteractionHistory()) {
			if (event.getStructureHandle() != null) {
				String storedUrl = RepositoryTaskHandleUtil.getRepositoryUrl(event.getStructureHandle());
				if (storedUrl != null) {
					if (oldRepositoryUrl.equals(storedUrl)) {
						String taskId = RepositoryTaskHandleUtil.getTaskId(event.getStructureHandle());
						if (taskId != null) {
							String newHandle = RepositoryTaskHandleUtil.getHandle(newRepositoryUrl, taskId);
							event = new InteractionEvent(event.getKind(), event.getStructureKind(), newHandle,
									event.getOriginId(), event.getNavigation(), event.getDelta(),
									event.getInterestContribution(), event.getDate(), event.getEndDate());
						}
					}
				}
			}
			newMetaContext.parseEvent(event);
		}
	}

	private void refactorRepositoryLocation(TaskRepository repository, String oldRepositoryUrl, String newRepositoryUrl) {
		IPath oldPath = new Path(repository.getConnectorKind() + "-" + CoreUtil.asFileName(oldRepositoryUrl)).append(FOLDER_DATA); //$NON-NLS-1$
		IPath newPath = new Path(repository.getConnectorKind() + "-" + CoreUtil.asFileName(newRepositoryUrl)).append(FOLDER_DATA); //$NON-NLS-1$
		try {
			getTaskStore().move(oldPath, newPath);
		} catch (CoreException e) {
			StatusHandler.log(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN, NLS.bind(
					"Failed to migrate data store for repository {0}", newRepositoryUrl), e)); //$NON-NLS-1$
		}
	}

	public ContextStatePersistenceHandler getStateHandler() {
		return stateHandler;
	}

}
