/*******************************************************************************
 * 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 java.util.HashMap;
import java.util.Map;

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;

import com.google.common.collect.ImmutableMap;

/**
 * @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
		moveTaskActivity(ImmutableMap.of(sourceTask.getHandleIdentifier(), targetTask.getHandleIdentifier()));

		moveContextInStore(sourceTask, targetTask);

		return asAdaptable(result);
	}

	@Override
	public void moveContext(Map<ITask, ITask> tasks) {
		Map<String, String> handles = new HashMap<>();
		for (ITask sourceTask : tasks.keySet()) {
			handles.put(sourceTask.getHandleIdentifier(), tasks.get(sourceTask).getHandleIdentifier());
			copyContextInternal(sourceTask, tasks.get(sourceTask));
		}

		moveTaskActivity(handles);

		for (ITask sourceTask : tasks.keySet()) {
			moveContextInStore(sourceTask, tasks.get(sourceTask));
		}
	}

	private void moveTaskActivity(Map<String, String> handles) {
		ChangeActivityHandleOperation operation = new ChangeActivityHandleOperation(handles);
		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
		}
	}

	private void moveContextInStore(ITask sourceTask, ITask targetTask) {
		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);
			}
		});
	}

	@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)) //$NON-NLS-1$
				.append(FOLDER_DATA);
		IPath newPath = new Path(repository.getConnectorKind() + "-" + CoreUtil.asFileName(newRepositoryUrl)) //$NON-NLS-1$
				.append(FOLDER_DATA);
		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;
	}

}
