/*******************************************************************************
 * Copyright (C) 2007-2010 The University of Manchester
 *
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.t2.workbench.file.impl;

import static java.awt.GraphicsEnvironment.isHeadless;
import static java.util.Collections.singleton;
import static javax.swing.SwingUtilities.invokeAndWait;
import static javax.swing.SwingUtilities.isEventDispatchThread;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import javax.swing.filechooser.FileFilter;

import net.sf.taverna.t2.lang.observer.MultiCaster;
import net.sf.taverna.t2.lang.observer.Observable;
import net.sf.taverna.t2.lang.observer.Observer;
import net.sf.taverna.t2.workbench.edits.EditManager;
import net.sf.taverna.t2.workbench.edits.EditManager.AbstractDataflowEditEvent;
import net.sf.taverna.t2.workbench.edits.EditManager.EditManagerEvent;
import net.sf.taverna.t2.workbench.file.DataflowInfo;
import net.sf.taverna.t2.workbench.file.DataflowPersistenceHandler;
import net.sf.taverna.t2.workbench.file.FileManager;
import net.sf.taverna.t2.workbench.file.FileType;
import net.sf.taverna.t2.workbench.file.events.ClosedDataflowEvent;
import net.sf.taverna.t2.workbench.file.events.ClosingDataflowEvent;
import net.sf.taverna.t2.workbench.file.events.FileManagerEvent;
import net.sf.taverna.t2.workbench.file.events.OpenedDataflowEvent;
import net.sf.taverna.t2.workbench.file.events.SavedDataflowEvent;
import net.sf.taverna.t2.workbench.file.events.SetCurrentDataflowEvent;
import net.sf.taverna.t2.workbench.file.exceptions.OpenException;
import net.sf.taverna.t2.workbench.file.exceptions.OverwriteException;
import net.sf.taverna.t2.workbench.file.exceptions.SaveException;
import net.sf.taverna.t2.workbench.file.exceptions.UnsavedException;

import org.apache.log4j.Logger;

import uk.org.taverna.scufl2.api.common.Scufl2Tools;
import uk.org.taverna.scufl2.api.container.WorkflowBundle;
import uk.org.taverna.scufl2.api.core.Workflow;
import uk.org.taverna.scufl2.api.profiles.Profile;

/**
 * Implementation of {@link FileManager}
 * 
 * @author Stian Soiland-Reyes
 */
public class FileManagerImpl implements FileManager {
	private static Logger logger = Logger.getLogger(FileManagerImpl.class);
	private static int nameIndex = 1;

	/**
	 * The last blank workflowBundle created using #newDataflow() until it has
	 * been changed - when this variable will be set to null again. Used to
	 * automatically close unmodified blank workflowBundles on open.
	 */
	private WorkflowBundle blankWorkflowBundle = null;
	@SuppressWarnings("unused")
	private EditManager editManager;
	private EditManagerObserver editManagerObserver = new EditManagerObserver();
	protected MultiCaster<FileManagerEvent> observers = new MultiCaster<>(this);
	/**
	 * Ordered list of open WorkflowBundle
	 */
	private LinkedHashMap<WorkflowBundle, OpenDataflowInfo> openDataflowInfos = new LinkedHashMap<>();
	private DataflowPersistenceHandlerRegistry dataflowPersistenceHandlerRegistry;
	private Scufl2Tools scufl2Tools = new Scufl2Tools();
	private WorkflowBundle currentWorkflowBundle;

	public DataflowPersistenceHandlerRegistry getPersistanceHandlerRegistry() {
		return dataflowPersistenceHandlerRegistry;
	}

	public FileManagerImpl(EditManager editManager) {
		this.editManager = editManager;
		editManager.addObserver(editManagerObserver);
	}

	/**
	 * Add an observer to be notified of {@link FileManagerEvent}s, such as
	 * {@link OpenedDataflowEvent} and {@link SavedDataflowEvent}.
	 * 
	 * {@inheritDoc}
	 */
	@Override
	public void addObserver(Observer<FileManagerEvent> observer) {
		observers.addObserver(observer);
	}

	@Override
	public boolean canSaveWithoutDestination(WorkflowBundle workflowBundle) {
		OpenDataflowInfo dataflowInfo = getOpenDataflowInfo(workflowBundle);
		if (dataflowInfo.getSource() == null)
			return false;
		Set<?> handlers = getPersistanceHandlerRegistry()
				.getSaveHandlersForType(
						dataflowInfo.getFileType(),
						dataflowInfo.getDataflowInfo().getCanonicalSource()
								.getClass());
		return !handlers.isEmpty();
	}

	@Override
	public boolean closeDataflow(WorkflowBundle workflowBundle,
			boolean failOnUnsaved) throws UnsavedException {
		if (workflowBundle == null)
			throw new NullPointerException("Dataflow can't be null");
		ClosingDataflowEvent message = new ClosingDataflowEvent(workflowBundle);
		observers.notify(message);
		if (message.isAbortClose())
			return false;
		if ((failOnUnsaved && getOpenDataflowInfo(workflowBundle).isChanged()))
			throw new UnsavedException(workflowBundle);
		if (workflowBundle.equals(getCurrentDataflow())) {
			// We'll need to change current workflowBundle
			// Find best candidate to the left or right
			List<WorkflowBundle> workflowBundles = getOpenDataflows();
			int openIndex = workflowBundles.indexOf(workflowBundle);
			if (openIndex == -1)
				throw new IllegalArgumentException("Workflow was not opened "
						+ workflowBundle);

			if (openIndex > 0)
				setCurrentDataflow(workflowBundles.get(openIndex - 1));
			else if (openIndex == 0 && workflowBundles.size() > 1)
				setCurrentDataflow(workflowBundles.get(1));
			else
				// If it was the last one, start a new, empty workflowBundle
				newDataflow();
		}
		if (workflowBundle == blankWorkflowBundle)
			blankWorkflowBundle = null;
		openDataflowInfos.remove(workflowBundle);
		observers.notify(new ClosedDataflowEvent(workflowBundle));
		return true;
	}

	@Override
	public WorkflowBundle getCurrentDataflow() {
		return currentWorkflowBundle;
	}

	@Override
	public WorkflowBundle getDataflowBySource(Object source) {
		for (Entry<WorkflowBundle, OpenDataflowInfo> infoEntry : openDataflowInfos
				.entrySet()) {
			OpenDataflowInfo info = infoEntry.getValue();
			if (source.equals(info.getSource()))
				return infoEntry.getKey();
		}
		// Not found
		return null;
	}

	@Override
	public String getDataflowName(WorkflowBundle workflowBundle) {
		Object source = null;
		if (isDataflowOpen(workflowBundle))
			source = getDataflowSource(workflowBundle);
		// Fallback
		String name;
		Workflow workflow = workflowBundle.getMainWorkflow();
		if (workflow != null)
			name = workflow.getName();
		else
			name = workflowBundle.getName();
		if (source == null)
			return name;
		if (source instanceof File)
			return ((File) source).getAbsolutePath();
		else if (source instanceof URL)
			return source.toString();

		// Check if it has implemented a toString() method
		Method toStringMethod = null;
		Method toStringMethodFromObject = null;
		try {
			toStringMethod = source.getClass().getMethod("toString");
			toStringMethodFromObject = Object.class.getMethod("toString");
		} catch (Exception e) {
			throw new IllegalStateException(
					"Source did not implement Object.toString() " + source);
		}
		if (!toStringMethod.equals(toStringMethodFromObject))
			return source.toString();
		return name;
	}

	@Override
	public String getDefaultWorkflowName() {
		return "Workflow" + (nameIndex++);
	}

	@Override
	public Object getDataflowSource(WorkflowBundle workflowBundle) {
		return getOpenDataflowInfo(workflowBundle).getSource();
	}

	@Override
	public FileType getDataflowType(WorkflowBundle workflowBundle) {
		return getOpenDataflowInfo(workflowBundle).getFileType();
	}

	@Override
	public List<Observer<FileManagerEvent>> getObservers() {
		return observers.getObservers();
	}

	/**
	 * Get the {@link OpenDataflowInfo} for the given WorkflowBundle
	 * 
	 * @throws NullPointerException
	 *             if the WorkflowBundle was <code>null</code>
	 * @throws IllegalArgumentException
	 *             if the WorkflowBundle was not open.
	 * @param workflowBundle
	 *            WorkflowBundle which information is to be found
	 * @return The {@link OpenDataflowInfo} describing the WorkflowBundle
	 */
	protected synchronized OpenDataflowInfo getOpenDataflowInfo(
			WorkflowBundle workflowBundle) {
		if (workflowBundle == null)
			throw new NullPointerException("Dataflow can't be null");
		OpenDataflowInfo info = openDataflowInfos.get(workflowBundle);
		if (info == null)
			throw new IllegalArgumentException("Workflow was not opened "
					+ workflowBundle);
		return info;
	}

	@Override
	public List<WorkflowBundle> getOpenDataflows() {
		return new ArrayList<>(openDataflowInfos.keySet());
	}

	@Override
	public List<FileFilter> getOpenFileFilters() {
		List<FileFilter> fileFilters = new ArrayList<>();

		Set<FileType> fileTypes = getPersistanceHandlerRegistry()
				.getOpenFileTypes();
		if (!fileTypes.isEmpty())
			fileFilters.add(new MultipleFileTypes(fileTypes,
					"All supported workflows"));
		for (FileType fileType : fileTypes)
			fileFilters.add(new FileTypeFileFilter(fileType));
		return fileFilters;
	}

	@Override
	public List<FileFilter> getOpenFileFilters(Class<?> sourceClass) {
		List<FileFilter> fileFilters = new ArrayList<>();
		for (FileType fileType : getPersistanceHandlerRegistry()
				.getOpenFileTypesFor(sourceClass))
			fileFilters.add(new FileTypeFileFilter(fileType));
		return fileFilters;
	}

	@Override
	public List<FileFilter> getSaveFileFilters() {
		List<FileFilter> fileFilters = new ArrayList<>();
		for (FileType fileType : getPersistanceHandlerRegistry()
				.getSaveFileTypes())
			fileFilters.add(new FileTypeFileFilter(fileType));
		return fileFilters;
	}

	@Override
	public List<FileFilter> getSaveFileFilters(Class<?> destinationClass) {
		List<FileFilter> fileFilters = new ArrayList<>();
		for (FileType fileType : getPersistanceHandlerRegistry()
				.getSaveFileTypesFor(destinationClass))
			fileFilters.add(new FileTypeFileFilter(fileType));
		return fileFilters;
	}

	@Override
	public boolean isDataflowChanged(WorkflowBundle workflowBundle) {
		return getOpenDataflowInfo(workflowBundle).isChanged();
	}

	@Override
	public boolean isDataflowOpen(WorkflowBundle workflowBundle) {
		return openDataflowInfos.containsKey(workflowBundle);
	}

	@Override
	public WorkflowBundle newDataflow() {
		WorkflowBundle workflowBundle = new WorkflowBundle();
		workflowBundle.setMainWorkflow(new Workflow());
		workflowBundle.getMainWorkflow().setName(getDefaultWorkflowName());
		workflowBundle.setMainProfile(new Profile());
		scufl2Tools.setParents(workflowBundle);
		blankWorkflowBundle = null;
		openDataflowInternal(workflowBundle);
		blankWorkflowBundle = workflowBundle;
		observers.notify(new OpenedDataflowEvent(workflowBundle));
		return workflowBundle;
	}

	@Override
	public void openDataflow(WorkflowBundle workflowBundle) {
		openDataflowInternal(workflowBundle);
		observers.notify(new OpenedDataflowEvent(workflowBundle));
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public WorkflowBundle openDataflow(FileType fileType, Object source)
			throws OpenException {
		if (isHeadless())
			return performOpenDataflow(fileType, source);

		OpenDataflowRunnable r = new OpenDataflowRunnable(this, fileType,
				source);
		if (isEventDispatchThread()) {
			r.run();
		} else
			try {
				invokeAndWait(r);
			} catch (InterruptedException | InvocationTargetException e) {
				throw new OpenException("Opening was interrupted", e);
			}
		OpenException thrownException = r.getException();
		if (thrownException != null)
			throw thrownException;
		return r.getDataflow();
	}

	public WorkflowBundle performOpenDataflow(FileType fileType, Object source)
			throws OpenException {
		DataflowInfo dataflowInfo;
		WorkflowBundle workflowBundle;
		dataflowInfo = openDataflowSilently(fileType, source);
		workflowBundle = dataflowInfo.getDataflow();
		openDataflowInternal(workflowBundle);
		getOpenDataflowInfo(workflowBundle).setOpenedFrom(dataflowInfo);
		observers.notify(new OpenedDataflowEvent(workflowBundle));
		return workflowBundle;
	}

	@Override
	public DataflowInfo openDataflowSilently(FileType fileType, Object source)
			throws OpenException {
		Set<DataflowPersistenceHandler> handlers;
		Class<? extends Object> sourceClass = source.getClass();

		boolean unknownFileType = (fileType == null);
		if (unknownFileType)
			handlers = getPersistanceHandlerRegistry().getOpenHandlersFor(
					sourceClass);
		else
			handlers = getPersistanceHandlerRegistry().getOpenHandlersFor(
					fileType, sourceClass);
		if (handlers.isEmpty())
			throw new OpenException("Unsupported file type or class "
					+ fileType + " " + sourceClass);

		Throwable lastException = null;
		for (DataflowPersistenceHandler handler : handlers) {
			Collection<FileType> fileTypes;
			if (unknownFileType)
				fileTypes = handler.getOpenFileTypes();
			else
				fileTypes = singleton(fileType);
			for (FileType candidateFileType : fileTypes) {
				if (unknownFileType && (source instanceof File))
					/*
					 * If source is file but fileType was not explicitly set
					 * from the open workflow dialog - check the file extension
					 * and decide which handler to use based on that (so that we
					 * do not loop though all handlers)
					 */
					if (!((File) source).getPath().endsWith(
							candidateFileType.getExtension()))
						continue;

				try {
					DataflowInfo openDataflow = handler.openDataflow(
							candidateFileType, source);
					WorkflowBundle workflowBundle = openDataflow.getDataflow();
					logger.info("Loaded workflow: " + workflowBundle.getName()
							+ " " + workflowBundle.getGlobalBaseURI()
							+ " from " + source + " using " + handler);
					return openDataflow;
				} catch (OpenException ex) {
					logger.warn("Could not open workflow " + source + " using "
							+ handler + " of type " + candidateFileType);
					lastException = ex;
				}
			}
		}
		throw new OpenException("Could not open workflow " + source + "\n",
				lastException);
	}

	/**
	 * Mark the WorkflowBundle as opened, and close the blank WorkflowBundle if
	 * needed.
	 * 
	 * @param workflowBundle
	 *            WorkflowBundle that has been opened
	 */
	protected void openDataflowInternal(WorkflowBundle workflowBundle) {
		if (workflowBundle == null)
			throw new NullPointerException("Dataflow can't be null");
		if (isDataflowOpen(workflowBundle))
			throw new IllegalArgumentException("Workflow is already open: "
					+ workflowBundle);

		openDataflowInfos.put(workflowBundle, new OpenDataflowInfo());
		setCurrentDataflow(workflowBundle);
		if (openDataflowInfos.size() == 2 && blankWorkflowBundle != null)
			/*
			 * Behave like a word processor and close the blank WorkflowBundle
			 * when another workflow has been opened
			 */
			try {
				closeDataflow(blankWorkflowBundle, true);
			} catch (UnsavedException e) {
				logger.error("Blank workflow was modified "
						+ "and could not be closed");
			}
	}

	@Override
	public void removeObserver(Observer<FileManagerEvent> observer) {
		observers.removeObserver(observer);
	}

	@Override
	public void saveDataflow(WorkflowBundle workflowBundle,
			boolean failOnOverwrite) throws SaveException {
		if (workflowBundle == null)
			throw new NullPointerException("Dataflow can't be null");
		OpenDataflowInfo lastSave = getOpenDataflowInfo(workflowBundle);
		if (lastSave.getSource() == null)
			throw new SaveException("Can't save without source "
					+ workflowBundle);
		saveDataflow(workflowBundle, lastSave.getFileType(),
				lastSave.getSource(), failOnOverwrite);
	}

	@Override
	public void saveDataflow(WorkflowBundle workflowBundle, FileType fileType,
			Object destination, boolean failOnOverwrite) throws SaveException {
		DataflowInfo savedDataflow = saveDataflowSilently(workflowBundle,
				fileType, destination, failOnOverwrite);
		getOpenDataflowInfo(workflowBundle).setSavedTo(savedDataflow);
		observers.notify(new SavedDataflowEvent(workflowBundle));
	}

	@Override
	public DataflowInfo saveDataflowSilently(WorkflowBundle workflowBundle,
			FileType fileType, Object destination, boolean failOnOverwrite)
			throws SaveException, OverwriteException {
		Set<DataflowPersistenceHandler> handlers;

		Class<? extends Object> destinationClass = destination.getClass();
		if (fileType != null)
			handlers = getPersistanceHandlerRegistry().getSaveHandlersForType(
					fileType, destinationClass);
		else
			handlers = getPersistanceHandlerRegistry().getSaveHandlersFor(
					destinationClass);

		SaveException lastException = null;
		for (DataflowPersistenceHandler handler : handlers) {
			if (failOnOverwrite) {
				OpenDataflowInfo openDataflowInfo = getOpenDataflowInfo(workflowBundle);
				if (handler.wouldOverwriteDataflow(workflowBundle, fileType,
						destination, openDataflowInfo.getDataflowInfo()))
					throw new OverwriteException(destination);
			}
			try {
				DataflowInfo savedDataflow = handler.saveDataflow(
						workflowBundle, fileType, destination);
				savedDataflow.getDataflow();
				logger.info("Saved workflow: " + workflowBundle.getName() + " "
						+ workflowBundle.getGlobalBaseURI() + " to "
						+ savedDataflow.getCanonicalSource() + " using "
						+ handler);
				return savedDataflow;
			} catch (SaveException ex) {
				logger.warn("Could not save to " + destination + " using "
						+ handler);
				lastException = ex;
			}
		}

		if (lastException == null)
			throw new SaveException("Unsupported file type or class "
					+ fileType + " " + destinationClass);
		throw new SaveException("Could not save to " + destination + ":\n"
				+ lastException.getLocalizedMessage(), lastException);
	}

	@Override
	public void setCurrentDataflow(WorkflowBundle workflowBundle) {
		setCurrentDataflow(workflowBundle, false);
	}

	@Override
	public void setCurrentDataflow(WorkflowBundle workflowBundle,
			boolean openIfNeeded) {
		currentWorkflowBundle = workflowBundle;
		if (!isDataflowOpen(workflowBundle)) {
			if (!openIfNeeded)
				throw new IllegalArgumentException("Workflow is not open: "
						+ workflowBundle);
			openDataflow(workflowBundle);
			return;
		}
		observers.notify(new SetCurrentDataflowEvent(workflowBundle));
	}

	@Override
	public void setDataflowChanged(WorkflowBundle workflowBundle,
			boolean isChanged) {
		getOpenDataflowInfo(workflowBundle).setIsChanged(isChanged);
		if (blankWorkflowBundle == workflowBundle)
			blankWorkflowBundle = null;
	}

	@Override
	public Object getCanonical(Object source) throws IllegalArgumentException,
			URISyntaxException, IOException {
		Object canonicalSource = source;

		if (source instanceof URL) {
			URL url = ((URL) source);
			if (url.getProtocol().equalsIgnoreCase("file"))
				canonicalSource = new File(url.toURI());
		}

		if (canonicalSource instanceof File)
			canonicalSource = ((File) canonicalSource).getCanonicalFile();
		return canonicalSource;
	}

	public void setDataflowPersistenceHandlerRegistry(
			DataflowPersistenceHandlerRegistry dataflowPersistenceHandlerRegistry) {
		this.dataflowPersistenceHandlerRegistry = dataflowPersistenceHandlerRegistry;
	}

	/**
	 * Observe the {@link EditManager} for changes to open workflowBundles. A
	 * change of an open workflow would set it as changed using
	 * {@link FileManagerImpl#setDataflowChanged(Dataflow, boolean)}.
	 * 
	 * @author Stian Soiland-Reyes
	 * 
	 */
	private final class EditManagerObserver implements
			Observer<EditManagerEvent> {
		@Override
		public void notify(Observable<EditManagerEvent> sender,
				EditManagerEvent message) throws Exception {
			if (message instanceof AbstractDataflowEditEvent) {
				AbstractDataflowEditEvent dataflowEdit = (AbstractDataflowEditEvent) message;
				WorkflowBundle workflowBundle = dataflowEdit.getDataFlow();
				/**
				 * TODO: on undo/redo - keep last event or similar to determine
				 * if workflow was saved before. See
				 * FileManagerTest#isChangedWithUndo().
				 */
				setDataflowChanged(workflowBundle, true);
			}
		}
	}
}
