/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
package org.eclipse.jdt.internal.junit.ui;


import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILauncher;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.ILauncherDelegate;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.WizardDialog;

import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;

import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;

import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMRunner;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.ProjectSourceLocator;
import org.eclipse.jdt.launching.VMRunnerConfiguration;
import org.eclipse.jdt.launching.VMRunnerResult;

/**
 * An abstract base launcher for running JUnit TestSuites.
 * Subclasses have to override: VMRunnerConfiguration configureVM(IType[] testTypes, int port)
 */
public abstract class JUnitBaseLauncherDelegate implements ILauncherDelegate, IJUnitLauncherDelegate {
	/**
	 * The run mode used to invoke the launcher.
	 */
	private String fRunMode;
	
	/** 
	 * The port we are connecting to
	 */
	private int fPort;
	
	/** 
	 * The type to be launched
	 */
	private IType fType;
	
	/**
	 * The launcher
	 */
	private ILauncher fLauncher;
	/**
	 * Configure a VM for the given test types.
	 */
 	protected abstract VMRunnerConfiguration configureVM(IType[] testTypes, int port, String mode) throws CoreException;
	
	/*
	 * @see ILauncherDelegate#launch(Object[], String, ILauncher)
	 */
	public boolean launch(Object[] objects, String mode, ILauncher launcher) {
		IStructuredSelection selection= new StructuredSelection(objects);
		Object[] elements= getLaunchableElements(selection);
		
		if (elements.length > 1)
			return useWizard(elements, selection, mode, launcher);

		if (elements.length == 0) {
			MessageDialog.openError(JUnitPlugin.getActiveWorkbenchShell(), 
				"JUnit Launcher", "Could not find a JUnit test class"
			);
			return true;
		}
		
		Object runnable= elements[0];
		if (!(runnable instanceof IType)) {
			MessageDialog.openError(JUnitPlugin.getActiveWorkbenchShell(), 
				"JUnit Launcher", "Could not find a launchable test type"
			);
			return true;
		}
		IType[] testTypes= new IType[] {(IType)runnable};
		return doLaunch(testTypes, mode, launcher);
	}

	protected boolean doLaunch(final IType[] testTypes, final String runMode, ILauncher launcher) {
		final IType testType= testTypes[0];
		fType= testType;
		
		IVMInstall vmInstall;
		try {
			vmInstall= JavaRuntime.getVMInstall(testType.getJavaProject());
		} catch (CoreException e) {
			ErrorDialog.openError(JUnitPlugin.getActiveWorkbenchShell(), "JUnit Launch", e.getMessage(), e.getStatus());
			return true;
		}
		if (vmInstall == null)
		   vmInstall= JavaRuntime.getDefaultVMInstall();
	    
	    if (vmInstall == null) {
	    	MessageDialog.openError(JUnitPlugin.getActiveWorkbenchShell(), "JUnit Launch", "No JRE Runtime found");
	    	return true;
	    }
	    
		final IVMRunner vmRunner= vmInstall.getVMRunner(runMode);	
		final VMRunnerResult returnResult[]= new VMRunnerResult[1];
		VMRunnerResult result;
		
		fPort= SocketUtil.findUnusedLocalPort(4000, 5000);  
		final int finalPort= fPort;
		
		IRunnableWithProgress runnable= new IRunnableWithProgress() {
			public void run(IProgressMonitor pm) throws InvocationTargetException {
				pm.beginTask("Starting VM ...", IProgressMonitor.UNKNOWN);
				try {
					VMRunnerConfiguration vmConfig= configureVM(testTypes, finalPort, runMode);
					returnResult[0]= vmRunner.run(vmConfig);
				} catch (CoreException e) {
					throw new InvocationTargetException(e);
				}
			}
		};
		try {
			new ProgressMonitorDialog(JUnitPlugin.getActiveWorkbenchShell()).run(true, false, runnable);		
		} catch (InterruptedException e) {
			// do nothing - user canceled action
		} catch (InvocationTargetException e) {
			Throwable te= e.getTargetException();
			JUnitPlugin.log(te);
			MessageDialog.openError(JUnitPlugin.getActiveWorkbenchShell(), "Could not launch VM", te.getMessage());			
			return false;
		}
		result= returnResult[0];
		if (result != null && launcher != null) {
			// TO DO should use JavaUISourceLocator, but this would break 1.0 compatibility
			Launch newLaunch= new Launch(launcher, runMode, testType.getCompilationUnit(), new ProjectSourceLocator(testType.getJavaProject()), result.getProcesses(), result.getDebugTarget());
			registerLaunch(newLaunch);
		}
		fLauncher= launcher;
		fRunMode= runMode;
		fType= testType;
		return true;
	}

	/*
	 * @see ILauncherDelegate#getLaunchMemento(Object)
	 */
	public String getLaunchMemento(Object element) {
		if (element instanceof IJavaElement) 
			return ((IJavaElement)element).getHandleIdentifier();
		return null;
	}

	/*
	 * @see ILauncherDelegate#getLaunchObject(String)
	 */
	public Object getLaunchObject(String memento) {
		IJavaElement e= JavaCore.create(memento);
		if (e.exists()) 
			return e;
		return null;
	}
	
	public String getRunMode() {
		return fRunMode;
	}
	
	public int getPort() {
		return fPort;
	}
	
	public IType getLaunchedType() {
		return fType;
	}
	
	/**
	 * Returns a collection of elements this launcher is capable of launching
	 * in the specified mode based on the given selection. If this launcher cannot launch any
	 * elements in the current selection, an empty collection or <code>null</code>
	 * is returned.
	 */
	public IType[] getLaunchableElements(IStructuredSelection selection) {
		try {
			ProgressMonitorDialog dialog= new ProgressMonitorDialog(JUnitPlugin.getActiveWorkbenchShell());
			return TestSearchEngine.findTargets(dialog, selection.toArray());
		} catch (InvocationTargetException e) {
			JUnitPlugin.log(e);
		} catch (InterruptedException e) {
			// user pressed cancel
		}
		return new IType[0];
	}

	/**
	 * Use the wizard to do the launch.
	 */
	private boolean useWizard(Object[] elements, IStructuredSelection selection, String mode, ILauncher launcher) {
		JUnitLaunchWizard wizard= new JUnitLaunchWizard(elements);
		wizard.init(launcher, mode, selection);
		Shell shell= JUnitPlugin.getActiveWorkbenchShell();
		if (shell != null) {
			WizardDialog dialog= new WizardDialog(shell, wizard);
			int status= dialog.open();
			return (status == dialog.OK || status == dialog.CANCEL);
		}
		return false;
	}

	/**
	 * Registers the Process in the Debug View
	 */
	private void registerLaunch(final ILaunch launch) {
		Display.getCurrent().syncExec(new Runnable() {
			public void run() {
				DebugPlugin.getDefault().getLaunchManager().registerLaunch(launch);
			}
		});
	}
}