/*******************************************************************************
 * 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.run.actions;

import static java.awt.Frame.ICONIFIED;
import static java.awt.Frame.NORMAL;
import static java.awt.Toolkit.getDefaultToolkit;
import static java.awt.event.KeyEvent.VK_R;
import static javax.swing.KeyStroke.getKeyStroke;
import static javax.swing.SwingUtilities.invokeLater;
import static net.sf.taverna.t2.reference.ui.InvalidDataflowReport.showErrorDialog;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.runIcon;

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import java.util.concurrent.ExecutionException;

import javax.swing.AbstractAction;

import net.sf.taverna.t2.lang.observer.Observable;
import net.sf.taverna.t2.lang.observer.Observer;
import net.sf.taverna.t2.reference.ui.CopyWorkflowInProgressDialog;
import net.sf.taverna.t2.reference.ui.CopyWorkflowSwingWorker;
import net.sf.taverna.t2.reference.ui.WorkflowLaunchWindow;
import net.sf.taverna.t2.reference.ui.referenceactions.ReferenceActionSPI;
import net.sf.taverna.t2.workbench.edits.EditManager;
import net.sf.taverna.t2.workbench.file.FileManager;
import net.sf.taverna.t2.workbench.file.events.ClosedDataflowEvent;
import net.sf.taverna.t2.workbench.file.events.FileManagerEvent;
import net.sf.taverna.t2.workbench.report.ReportManager;
import net.sf.taverna.t2.workbench.selection.SelectionManager;
import net.sf.taverna.t2.workbench.ui.SwingWorkerCompletionWaiter;
import net.sf.taverna.t2.workbench.ui.Workbench;

import org.apache.log4j.Logger;
import org.purl.wf4ever.robundle.Bundle;

import uk.org.taverna.databundle.DataBundles;
import uk.org.taverna.platform.execution.api.ExecutionEnvironment;
import uk.org.taverna.platform.execution.api.InvalidExecutionIdException;
import uk.org.taverna.platform.execution.api.InvalidWorkflowException;
import uk.org.taverna.platform.run.api.InvalidRunIdException;
import uk.org.taverna.platform.run.api.RunProfile;
import uk.org.taverna.platform.run.api.RunProfileException;
import uk.org.taverna.platform.run.api.RunService;
import uk.org.taverna.platform.run.api.RunStateException;
import uk.org.taverna.scufl2.api.container.WorkflowBundle;
import uk.org.taverna.scufl2.api.profiles.Profile;

/**
 * Run the current workflow (with workflow input dialogue if needed) and add it
 * to the list of runs.
 * <p>
 * Note that running a workflow will force a clone of the WorkflowBundle, allowing further edits to
 * the current WorkflowBundle without obstructing the run.
 */
@SuppressWarnings("serial")
public class RunWorkflowAction extends AbstractAction {
	private static Logger logger = Logger.getLogger(RunWorkflowAction.class);

	/**
	 * A map of workflows and their corresponding {@link WorkflowLaunchWindow}s.
	 * We only create one window per workflow and then update its content if the
	 * workflow gets updated
	 */
	private static HashMap<WorkflowBundle, WorkflowLaunchWindow> workflowLaunchWindowMap = new HashMap<>();

	private final EditManager editManager;
	private final FileManager fileManager;
	private final ReportManager reportManager;
	private final Workbench workbench;
	private final RunService runService;
	private final SelectionManager selectionManager;

	public RunWorkflowAction(EditManager editManager, FileManager fileManager,
			ReportManager reportManager, Workbench workbench, RunService runService,
			SelectionManager selectionManager) {
		this.editManager = editManager;
		this.fileManager = fileManager;
		this.reportManager = reportManager;
		this.workbench = workbench;
		this.runService = runService;
		this.selectionManager = selectionManager;
		putValue(SMALL_ICON, runIcon);
		putValue(NAME, "Run workflow...");
		putValue(SHORT_DESCRIPTION, "Run the current workflow");
		putValue(MNEMONIC_KEY, VK_R);
		putValue(
				ACCELERATOR_KEY,
				getKeyStroke(VK_R, getDefaultToolkit().getMenuShortcutKeyMask()));
		fileManager.addObserver(new Observer<FileManagerEvent>() {
			@Override
			public void notify(Observable<FileManagerEvent> sender, FileManagerEvent message)
					throws Exception {
				if (message instanceof ClosedDataflowEvent)
					workflowLaunchWindowMap
							.remove(((ClosedDataflowEvent) message)
									.getDataflow());
			}
		});
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		final WorkflowBundle workflowBundle = selectionManager.getSelectedWorkflowBundle();
		final Profile profile = selectionManager.getSelectedProfile();
		Set<ExecutionEnvironment> executionEnvironments = runService
				.getExecutionEnvironments(profile);
		if (executionEnvironments.isEmpty()) {
			showErrorDialog(
					"There are no execution environments capable of running this workflow",
					"Can't run workflow");
			return;
		}

		// TODO ask user to choose execution environment
		final ExecutionEnvironment executionEnvironment = executionEnvironments.iterator().next();
		try {
			if (validate(workflowBundle, profile)) {
				if (workflowBundle.getMainWorkflow().getInputPorts().isEmpty()) {
					final Bundle bundle = DataBundles.createBundle();
					invokeLater(new Runnable() {
						@Override
						public void run() {
							runWorkflow(workflowBundle, profile,
									executionEnvironment, bundle);
						}
					});
				} else // workflow had inputs - show the input dialog
					invokeLater(new Runnable() {
						@Override
						public void run() {
							showInputDialog(workflowBundle, profile,
									executionEnvironment);
						}
					});
				}
		} catch (Exception ex) {
			String message = "Could not run workflow " + workflowBundle.getName();
			logger.warn(message);
			showErrorDialog(ex.getMessage(), message);
		}
	}

	// TODO update to use Scufl2 validation
	private boolean validate(WorkflowBundle workflowBundle, Profile selectedProfile) {
		//CheckWorkflowStatus.checkWorkflow(selectedProfile, workbench, editManager,
		//		fileManager,reportManager);
		return true;
	}

	private void runWorkflow(WorkflowBundle workflowBundle, Profile profile,
			ExecutionEnvironment executionEnvironment, Bundle workflowInputs) {
		try {
			RunProfile runProfile = createRunProfile(workflowBundle, profile,
					executionEnvironment, workflowInputs);
			if (runProfile != null) {
				String runId = runService.createRun(runProfile);
				runService.start(runId);
			}
		} catch (InvalidWorkflowException | RunProfileException | InvalidRunIdException
				| RunStateException | InvalidExecutionIdException e) {
			String message = "Could not run workflow " + workflowBundle.getName();
			logger.warn(message, e);
			showErrorDialog(e.getMessage(), message);
		}
	}

	private RunProfile createRunProfile(WorkflowBundle workflowBundle, Profile profile,
			ExecutionEnvironment executionEnvironment, Bundle inputDataBundle) {
		/*
		 * Make a copy of the workflow to run so user can still modify the
		 * original workflow
		 */
		WorkflowBundle workflowBundleCopy = null;

		/*
		 * CopyWorkflowSwingWorker will make a copy of the workflow and pop up a
		 * modal dialog that will block the GUI while CopyWorkflowSwingWorker is
		 * doing it to let the user know that something is being done. Blocking
		 * of the GUI is needed here so that the user cannot modify the original
		 * workflow while it is being copied.
		 */
		CopyWorkflowSwingWorker copyWorkflowSwingWorker = new CopyWorkflowSwingWorker(
				workflowBundle);

		CopyWorkflowInProgressDialog dialog = new CopyWorkflowInProgressDialog();
		copyWorkflowSwingWorker.addPropertyChangeListener(new SwingWorkerCompletionWaiter(dialog));
		copyWorkflowSwingWorker.execute();

		/*
		 * Give a chance to the SwingWorker to finish so we do not have to
		 * display the dialog if copying of the workflow is quick (so it won't
		 * flicker on the screen)
		 */
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			// do nothing
		}

		if (!copyWorkflowSwingWorker.isDone())
			dialog.setVisible(true); // this will block the GUI
		// see if user cancelled the dialog
		boolean userCancelled = dialog.hasUserCancelled();

		if (userCancelled) {
			// Stop the CopyWorkflowSwingWorker if it is still working
			copyWorkflowSwingWorker.cancel(true);
			return null;
		}

		// Get the workflow copy from the copyWorkflowSwingWorker
		try {
			workflowBundleCopy = copyWorkflowSwingWorker.get();
		} catch (InterruptedException | ExecutionException e) {
			logger.error("Failed to get the workflow copy", e);
		}

		if (workflowBundleCopy == null) {
			showErrorDialog("Unable to make a copy of the workflow to run",
					"Workflow copy failed");
			return null;
		}

		return new RunProfile(executionEnvironment, workflowBundleCopy,
				workflowBundleCopy.getMainWorkflow().getName(),
				profile.getName(), inputDataBundle);
	}

	private void showInputDialog(final WorkflowBundle workflowBundle,
			final Profile profile,
			final ExecutionEnvironment executionEnvironment) {
		// Get the WorkflowLauchWindow
		WorkflowLaunchWindow launchWindow = null;
		synchronized (workflowLaunchWindowMap) {
			WorkflowLaunchWindow savedLaunchWindow = workflowLaunchWindowMap
					.get(workflowBundle);
			if (savedLaunchWindow == null) {
				launchWindow = new WorkflowLaunchWindow(
						workflowBundle.getMainWorkflow(), editManager,
						fileManager, reportManager, workbench,
						new ArrayList<ReferenceActionSPI>(), null) {
					@Override
					public void handleLaunch(Bundle workflowInputs) {
						runWorkflow(workflowBundle, profile,
								executionEnvironment, workflowInputs);
						//TODO T2 now makes the launch window vanish
						setState(ICONIFIED); // minimise the window
					}

					@Override
					public void handleCancel() {
						// Keep the window so we do not have to rebuild it again
						setVisible(false);
					}
				};

				/*
				 * Add this window to the map of the workflow input/launch
				 * windows
				 */
				workflowLaunchWindowMap.put(workflowBundle, launchWindow);
				launchWindow.setLocationRelativeTo(null);
			} else
				launchWindow = savedLaunchWindow;

			// Display the window
			launchWindow.setVisible(true);
			/*
			 * On Win XP setting the window visible seems not to be enough to
			 * bring the window up if it was minimised previously so we restore
			 * it here
			 */
			if (launchWindow.getState() == ICONIFIED)
				launchWindow.setState(NORMAL); // restore the window
		}
	}
}
