/*******************************************************************************
 * 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.tasks.ui.util;

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.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Queue;
import java.util.Set;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.context.core.ContextCore;
import org.eclipse.mylyn.context.core.IInteractionContextManager;
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
import org.eclipse.mylyn.internal.tasks.ui.TaskListManager;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.ITaskListChangeListener;
import org.eclipse.mylyn.tasks.core.TaskContainerDelta;

//import org.eclipse.ui.PlatformUI;

/**
 * @author Mik Kersten
 * @author Eugene Kuleshov
 * @author Rob Elves
 */
public class TaskListSaveManager implements ITaskListChangeListener, IBackgroundSaveListener {

	private final static int DEFAULT_SAVE_INTERVAL = 1 * 60 * 1000;

	private final BackgroundSaveTimer saveTimer;

	private final TaskListSaverJob taskListSaverJob;

	private final boolean initializationWarningDialogShow = false;

	private static final int MAX_TASKLIST_SNAPSHOTS = 8;

	public static final Pattern SNAPSHOT_REGEXP = Pattern.compile("^tasklist-.*");

	public TaskListSaveManager() {
		saveTimer = new BackgroundSaveTimer(this);
		saveTimer.setSaveIntervalMillis(DEFAULT_SAVE_INTERVAL);
		saveTimer.start();

		taskListSaverJob = new TaskListSaverJob();
		//taskListSaverJob.setRule(TasksUiPlugin.getTaskList());
		taskListSaverJob.schedule();
	}

	/**
	 * Called periodically by the save timer
	 */
	public void saveRequested() {
		if (TasksUiPlugin.getDefault() != null && Platform.isRunning()) {// &&
			// TasksUiPlugin.getDefault().isShellActive()
			try {
				taskListSaverJob.runRequested();
			} catch (Exception e) {
				StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not auto save task list", e));
			}
		}
	}

	/**
	 * Should only be used by TaskListManager and unit tests
	 * 
	 * @param saveContext
	 * @param async
	 */
	public void saveTaskList(boolean saveContext, boolean async) {
		if (TasksUiPlugin.getDefault() != null && TasksUiPlugin.getDefault().isInitialized()) {
			TaskListManager taskListManager = TasksUiPlugin.getTaskListManager();
			if (async) {
				if (saveContext) {
					AbstractTask task = taskListManager.getActiveTask();
					if (task != null) {
						taskListSaverJob.addTaskContext(task);
					}
				}
				taskListSaverJob.requestSave();
			} else {
				taskListSaverJob.waitSaveCompleted();
				IInteractionContextManager contextManager = ContextCore.getContextManager();
				if (saveContext) {
					AbstractTask task = taskListManager.getActiveTask();
					if (task != null) {
						contextManager.saveContext(task.getHandleIdentifier());
					}
				}
				internalSaveTaskList();
			}
		} /*else if (PlatformUI.getWorkbench() != null && !PlatformUI.getWorkbench().isClosing()) {
									StatusHandler.fail(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN,
											"Possible task list initialization failure, not saving list"));
									if (!initializationWarningDialogShow) {
										initializationWarningDialogShow = true;
										PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
											public void run() {
												if (PlatformUI.getWorkbench() != null && PlatformUI.getWorkbench().getDisplay() != null) {
													MessageDialog.openInformation(
															PlatformUI.getWorkbench().getDisplay().getActiveShell(),
															ITasksUiConstants.TITLE_DIALOG,
															"If task list is blank, Mylyn Task List may have failed to initialize.\n\n"
																	+ "First, try restarting to see if that corrects the problem.\n\n"
																	+ "Then, check the Error Log view for messages, and the FAQ for solutions.\n\n"
																	+ ITasksUiConstants.URL_HOMEPAGE);
												}
											}
										});
									}*/
		//}
	}

	private synchronized void internalSaveTaskList() {
		TaskListManager taskListManager = TasksUiPlugin.getTaskListManager();
		File current = taskListManager.getTaskListFile();
		SimpleDateFormat format = new SimpleDateFormat(ITasksCoreConstants.TIMESTAMP_FORMAT, Locale.ENGLISH);
		String date = format.format(new Date());
		String backupFileName = ITasksCoreConstants.PREFIX_TASKLIST + "-" + date + ITasksCoreConstants.FILE_EXTENSION;

		String destination = TasksUiPlugin.getDefault().getBackupFolderPath();

		File backupFolder = new File(destination);
		if (!backupFolder.exists()) {
			backupFolder.mkdir();
		}

		File backup = new File(backupFolder, backupFileName);
		if (current.renameTo(backup)) {
			TasksUiPlugin.getBackupManager().removeOldBackups();

			String newTasklistPath = TasksUiPlugin.getDefault().getDataDirectory() + File.separator
					+ ITasksCoreConstants.DEFAULT_TASK_LIST_FILE;
			File newTaskListFile = new File(newTasklistPath);
			taskListManager.setTaskListFile(newTaskListFile);
		} else {
			StatusHandler.log(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN,
					"Unable to create task list snapshot " + backup.getAbsolutePath()));
		}

		taskListManager.getTaskListWriter().writeTaskList(taskListManager.getTaskList(),
				taskListManager.getTaskListFile());
	}

	/**
	 * Copies all files in the current data directory to the specified folder. Will overwrite.
	 */
	public void copyDataDirContentsTo(String targetFolderPath) {
		saveTaskList(true, false);

		File mainDataDir = new File(TasksUiPlugin.getDefault().getDataDirectory());

		for (File currFile : mainDataDir.listFiles()) {
			if (currFile.isFile()) {
				File destFile = new File(targetFolderPath + File.separator + currFile.getName());
				copy(currFile, destFile);
			} else if (currFile.isDirectory()) {
				File destDir = new File(targetFolderPath + File.separator + currFile.getName());
				if (!destDir.exists()) {
					if (!destDir.mkdir()) {
						StatusHandler.log(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN,
								"Unable to create destination context folder: " + destDir.getAbsolutePath()));
						continue;
					}
				}
				for (File file : currFile.listFiles()) {
					File destFile = new File(destDir, file.getName());
					if (destFile.exists()) {
						destFile.delete();
					}
					copy(file, destFile);
				}
			}
		}
	}

	// public void createTaskListBackupFile() {
	// String path = TasksUiPlugin.getDefault().getDataDirectory() +
	// File.separator
	// + TasksUiPlugin.DEFAULT_TASK_LIST_FILE;
	// File taskListFile = new File(path);
	// String backup = path.substring(0, path.indexOf('.')) +
	// FILE_SUFFIX_BACKUP;
	// copy(taskListFile, new File(backup));
	// }
	//
	// public String getBackupFilePath() {
	// String path = TasksUiPlugin.getDefault().getDataDirectory() +
	// File.separator
	// + TasksUiPlugin.DEFAULT_TASK_LIST_FILE;
	// return path.substring(0, path.indexOf('.')) + FILE_SUFFIX_BACKUP;
	// }
	//
	// public void reverseBackup() {
	// String path = TasksUiPlugin.getDefault().getBackupFolderPath() +
	// File.separator
	// + TasksUiPlugin.DEFAULT_TASK_LIST_FILE;
	// File taskListFile = new File(path);
	// String backup = path.substring(0, path.indexOf('.')) +
	// FILE_SUFFIX_BACKUP;
	// copy(new File(backup), taskListFile);
	// }

	private boolean copy(File src, File dst) {
		try {
			InputStream in = new FileInputStream(src);
			OutputStream out = new FileOutputStream(dst);

			// Transfer bytes from in to out
			byte[] buf = new byte[1024];
			int len;
			while ((len = in.read(buf)) > 0) {
				out.write(buf, 0, len);
			}
			in.close();
			out.close();
			return true;
		} catch (IOException ioe) {
			return false;
		}
	}

	public void taskActivated(AbstractTask task) {
		// ignore
	}

	public void tasksActivated(List<AbstractTask> tasks) {
		// ignore
	}

	public void taskDeactivated(AbstractTask task) {
		saveTaskList(true, true);
	}

	public void localInfoChanged(AbstractTask task) {
		saveTaskList(false, true);
	}

	public void repositoryInfoChanged(AbstractTask task) {
		// ignore
	}

	/** For testing only * */
	public BackgroundSaveTimer getSaveTimer() {
		return saveTimer;
	}

	public void containersChanged(Set<TaskContainerDelta> containers) {
		saveTaskList(false, true);
	}

	public void synchronizationCompleted() {
		// ignore
	}

	private class TaskListSaverJob extends Job {

		private final Queue<AbstractTask> taskQueue = new LinkedList<AbstractTask>();

		private volatile boolean saveRequested = false;

		private volatile boolean saveCompleted = true;

		TaskListSaverJob() {
			super("Task List Saver");
			setPriority(Job.LONG);
			setSystem(true);
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			while (true) {
				if (saveRequested) {
					saveRequested = false;
					saveCompleted = false;
					IInteractionContextManager contextManager = ContextCore.getContextManager();
					while (!taskQueue.isEmpty()) {
						AbstractTask task = taskQueue.poll();
						if (task != null) {
							contextManager.saveContext(task.getHandleIdentifier());
						}
					}
					internalSaveTaskList();
				}

				if (!saveRequested) {
					synchronized (this) {
						saveCompleted = true;
						notifyAll();
						try {
							wait();
						} catch (InterruptedException ex) {
							// ignore
						}
					}
				}
			}
		}

		void addTaskContext(AbstractTask task) {
			taskQueue.add(task);
		}

		void requestSave() {
			saveRequested = true;
		}

		void runRequested() {
			synchronized (this) {
				notifyAll();
			}
		}

		void waitSaveCompleted() {
			while (!saveCompleted) {
				synchronized (this) {
					try {
						wait();
					} catch (InterruptedException ex) {
						// ignore
					}
				}
			}
		}
	}

	public void taskListRead() {
	}

}
