/*******************************************************************************
 * Copyright (c) 2000, 2012 IBM Corporation 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
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.debug.tests.launching;

import java.util.Arrays;
import java.util.HashSet;

import junit.framework.AssertionFailedError;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchDelegate;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.ILaunchMode;
import org.eclipse.debug.internal.core.LaunchManager;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationPresentationManager;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
import org.eclipse.debug.ui.CommonTab;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.EnvironmentTab;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.debug.ui.ILaunchConfigurationTabGroup;
import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
import org.eclipse.jdt.debug.testplugin.launching.TestModeLaunchDelegate;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.debug.ui.launchConfigurations.JavaArgumentsTab;
import org.eclipse.jdt.debug.ui.launchConfigurations.JavaClasspathTab;
import org.eclipse.jdt.debug.ui.launchConfigurations.JavaJRETab;
import org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.ui.JavaUI;

/**
 * LaunchModeTests
 */
public class LaunchModeTests extends AbstractDebugTest {
	
	private ILaunchConfiguration fConfiguration;
	private String fMode;

	/**
	 * @param name
	 */
	public LaunchModeTests(String name) {
		super(name);
	}

	/**
	 * Called by launch "TestModeLaunchDelegate" delegate when launch method invoked.
	 * 
	 * @param configuration
	 * @param mode
	 */
	public synchronized void launch(ILaunchConfiguration configuration, String mode) {
		fConfiguration = configuration;
		fMode = mode;
		notifyAll();
	}

	/**
	 * Tests that launch delegate for "TEST_MODE" and Java applications is invoked when
	 * "TEST_MODE" is used.
	 * 
	 * @throws CoreException
	 * @see TestModeLaunchDelegate
	 */
	public void testContributedLaunchMode() throws CoreException {
		ILaunch launch = null;
		try {
			fConfiguration = null;
			fMode = null;
			TestModeLaunchDelegate.setTestCase(this);
			ILaunchConfiguration configuration = getLaunchConfiguration("Breakpoints"); //$NON-NLS-1$
			assertNotNull(configuration);
			launch = configuration.launch("TEST_MODE", null); //$NON-NLS-1$
			assertEquals("Launch delegate not invoked", configuration, getLaunchConfigurationSetByDelegate()); //$NON-NLS-1$
			assertEquals("Launch delegate not invoked in correct mode", "TEST_MODE", fMode); //$NON-NLS-1$ //$NON-NLS-2$
		} finally {
			TestModeLaunchDelegate.setTestCase(null);
			fConfiguration = null;
			fMode = null;
			if (launch != null) {
				getLaunchManager().removeLaunch(launch);
			}
		}
	}
	
	/**
	 * Returns the launch configuration set by the TestModeLaunchDelegate, or <code>null</code>
	 * if no launch configuration was set (the correct delegate was not called).
	 * A wait must occur due to the use of Jobs for launching.
	 */
	private synchronized Object getLaunchConfigurationSetByDelegate() {
		if (fConfiguration == null) {
			try {
				wait(10000);
			} catch (InterruptedException ie) {
				System.err.println("Interrupted waiting for launch configuration"); //$NON-NLS-1$
			}
		}
		
		return fConfiguration;
	}
	
	/**
	 * Ensure our contributed launch mode exists.
	 */
	public void testLaunchModes() {
		ILaunchMode[] modes = getLaunchManager().getLaunchModes();
		String[] ids = new String[modes.length];
		for (int i = 0; i < modes.length; i++) {
			ILaunchMode mode = modes[i];
			ids[i] = mode.getIdentifier();
		}
		assertContains("Missing TEST_MODE", ids, "TEST_MODE"); //$NON-NLS-1$ //$NON-NLS-2$
		assertContains("Missing debug mode", ids, ILaunchManager.DEBUG_MODE); //$NON-NLS-1$
		assertContains("Missing run mode", ids, ILaunchManager.RUN_MODE); //$NON-NLS-1$
		assertContains("Missing TEST_MODE", ids, "alternate"); //$NON-NLS-1$ //$NON-NLS-2$
	}
	
	/**
	 * Asserts that the array contains the given object
	 * @param message
	 * @param array
	 * @param object
	 */
	static public void assertContains(String message, Object[] array, Object object) {
		for (int i = 0; i < array.length; i++) {
			if (array[i].equals(object)) {
				return;
			}			
		}
		throw new AssertionFailedError(message);
	}	

	/**
	 * Ensure our contributed mode is supported.
	 * @throws CoreException
	 */
	public void testSupportsMode() throws CoreException {
		ILaunchConfiguration configuration = getLaunchConfiguration("Breakpoints"); //$NON-NLS-1$
		assertNotNull(configuration);
		assertTrue("Java application configuration should support TEST_MODE", configuration.supportsMode("TEST_MODE")); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Java application type should support TEST_MODE", configuration.getType().supportsMode("TEST_MODE")); //$NON-NLS-1$ //$NON-NLS-2$
		
		assertTrue("Java application configuration should support debug mode", configuration.supportsMode(ILaunchManager.DEBUG_MODE)); //$NON-NLS-1$
		assertTrue("Java application type should support debug mode", configuration.getType().supportsMode(ILaunchManager.DEBUG_MODE)); //$NON-NLS-1$
		
		assertTrue("Java application configuration should support run mode", configuration.supportsMode(ILaunchManager.RUN_MODE)); //$NON-NLS-1$
		assertTrue("Java application type should support run mode", configuration.getType().supportsMode(ILaunchManager.RUN_MODE));		 //$NON-NLS-1$
	}
	
	/**
	 * Tests that mode specific tab group contributions work.
	 * @throws CoreException
	 */
	public void testModeSpecificTabGroups() throws CoreException {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION); 
		ILaunchConfigurationTabGroup standardGroup = LaunchConfigurationPresentationManager.getDefault().getTabGroup(javaType, ILaunchManager.DEBUG_MODE);
		ILaunchConfigurationTabGroup testGroup = LaunchConfigurationPresentationManager.getDefault().getTabGroup(javaType, "TEST_MODE"); //$NON-NLS-1$
		ILaunchConfigurationDialog dialog = new LaunchConfigurationsDialog(null, DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(IDebugUIConstants.ID_DEBUG_LAUNCH_GROUP));
		standardGroup.createTabs(dialog, ILaunchManager.DEBUG_MODE);
		testGroup.createTabs(dialog, "TEST_MODE"); //$NON-NLS-1$
		
		ILaunchConfigurationTab[] tabs = standardGroup.getTabs();
		HashSet<Class<? extends ILaunchConfigurationTab>> tabset = new HashSet<Class<? extends ILaunchConfigurationTab>>();
		for(int i = 0; i< tabs.length; i++) {
			tabset.add(tabs[i].getClass());
		}
		Class<?>[] classes = new Class<?>[] {
				JavaMainTab.class, 
				JavaArgumentsTab.class, 
				JavaJRETab.class, 
				JavaClasspathTab.class,
				SourceLookupTab.class, 
				EnvironmentTab.class, 
				CommonTab.class};
		assertTrue("Tab set does not contain all default java tabs", tabset.containsAll(new HashSet<Class<?>>(Arrays.asList(classes)))); //$NON-NLS-1$
		
		tabs = testGroup.getTabs();
		assertEquals("Wrong number of tabs in the test group", 4, tabs.length); //$NON-NLS-1$
		tabset = new HashSet<Class<? extends ILaunchConfigurationTab>>();
		for(int i = 0; i< tabs.length; i++) {
			tabset.add(tabs[i].getClass());
		}
		classes = new Class<?>[] {
				JavaMainTab.class, 
				JavaArgumentsTab.class, 
				JavaJRETab.class, 
				JavaClasspathTab.class};
		assertTrue("Test tab set does not contain all default tabs", tabset.containsAll(new HashSet<Class<?>>(Arrays.asList(classes)))); //$NON-NLS-1$
		standardGroup.dispose();
		testGroup.dispose();
	}
	
	/**
	 * Tests that the default debug perspective for java applications is debug.
	 */
	public void testDefaultDebugLaunchPerspective() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		assertEquals("Java debug perspective should be debug", IDebugUIConstants.ID_DEBUG_PERSPECTIVE, DebugUITools.getLaunchPerspective(javaType, ILaunchManager.DEBUG_MODE)); //$NON-NLS-1$
	}
	
	/**
	 * Test that the default debug perspective for Java Application types is debug.
	 * Same notion as <code>testDefaultDebugLaunchPerspective()</code>, but using the new API
	 * for getting perspectives
	 * 
	 * @since 3.3
	 */
	public void testDefaultDebugLaunchPerspective2() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		HashSet<String> modes =  new HashSet<String>();
		modes.add(ILaunchManager.DEBUG_MODE);
		assertEquals("Java debug perspective should be debug", IDebugUIConstants.ID_DEBUG_PERSPECTIVE, DebugUITools.getLaunchPerspective(javaType, null, modes)); //$NON-NLS-1$
	}
	
	/**
	 * Tests that the default run perspective for java applications is none (<code>null</code>).
	 */
	public void testDefaultRunLaunchPerspective() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		assertNull("Java run perspective should be null", DebugUITools.getLaunchPerspective(javaType, ILaunchManager.RUN_MODE)); //$NON-NLS-1$
	}	
	
	/**
	 * Tests that the default run perspective for java applications is none (<code>null</code>).
	 * Same notion as <code>testDefaultRunLaunchPerspective()</code>, but using the new API for getting
	 * launch perspectives
	 * 
	 * @since 3.3
	 */
	public void testDefaultRunLaunchPerspective2() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		HashSet<String> modes = new HashSet<String>();
		modes.add(ILaunchManager.RUN_MODE);
		assertNull("Java run perspective should be null", DebugUITools.getLaunchPerspective(javaType, null, modes)); //$NON-NLS-1$
	}
	
	/**
	 * Tests that the default debug perspective can be over-ridden and reset
	 */
	public void testResetDebugLaunchPerspective() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		assertEquals("Java debug perspective should be debug", IDebugUIConstants.ID_DEBUG_PERSPECTIVE, //$NON-NLS-1$
			DebugUITools.getLaunchPerspective(javaType, ILaunchManager.DEBUG_MODE));
		// set to NONE
		DebugUITools.setLaunchPerspective(javaType, ILaunchManager.DEBUG_MODE, IDebugUIConstants.PERSPECTIVE_NONE);
		assertNull("Java debug perspective should now be null",  //$NON-NLS-1$
			DebugUITools.getLaunchPerspective(javaType, ILaunchManager.DEBUG_MODE));
		// re-set to default
		DebugUITools.setLaunchPerspective(javaType, ILaunchManager.DEBUG_MODE, IDebugUIConstants.PERSPECTIVE_DEFAULT);
		assertEquals("Java debug perspective should now be debug", IDebugUIConstants.ID_DEBUG_PERSPECTIVE, //$NON-NLS-1$
			DebugUITools.getLaunchPerspective(javaType, ILaunchManager.DEBUG_MODE));
				
	}	
	
	/**
	 * Tests that the default debug perspective can be over-ridden and reset.
	 * Same notion as <code>testResetDebugLaunchPerspective()</code>, but using the new API
	 * for setting an resetting perspectives.
	 * 
	 * @since 3.3
	 */
	public void testResetDebugLaunchPerspective2() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		HashSet<String> modes = new HashSet<String>();
		modes.add(ILaunchManager.DEBUG_MODE);
		assertEquals("Java debug perspective should be debug", IDebugUIConstants.ID_DEBUG_PERSPECTIVE, DebugUITools.getLaunchPerspective(javaType, null, modes)); //$NON-NLS-1$
		// set to NONE
		DebugUITools.setLaunchPerspective(javaType, null, modes, IDebugUIConstants.PERSPECTIVE_NONE);
		assertNull("Java debug perspective should now be null", DebugUITools.getLaunchPerspective(javaType, null, modes)); //$NON-NLS-1$
		// re-set to default
		DebugUITools.setLaunchPerspective(javaType, null, modes, IDebugUIConstants.PERSPECTIVE_DEFAULT);
		assertEquals("Java debug perspective should now be debug", IDebugUIConstants.ID_DEBUG_PERSPECTIVE, DebugUITools.getLaunchPerspective(javaType, null, modes)); //$NON-NLS-1$
				
	}	
	
	/**
	 * Tests that the default debug perspective can be over-ridden and reset
	 * Same notion as <code>testResetDebugLaunchPerspective2()</code>, but using the 
	 * JDT Java launch delegate instead of <code>null</code>
	 * 
	 * @since 3.3
	 */
	public void testResetDebugPerspectiveJavaLaunchDelegate() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		HashSet<String> modes = new HashSet<String>();
		modes.add(ILaunchManager.DEBUG_MODE);
		ILaunchDelegate delegate = ((LaunchManager)getLaunchManager()).getLaunchDelegate("org.eclipse.jdt.launching.localJavaApplication"); //$NON-NLS-1$
		assertNotNull("Java launch delegate should not be null", delegate); //$NON-NLS-1$
		assertEquals("Java debug perspective should be debug", IDebugUIConstants.ID_DEBUG_PERSPECTIVE, DebugUITools.getLaunchPerspective(javaType, delegate, modes)); //$NON-NLS-1$
		// set to NONE
		DebugUITools.setLaunchPerspective(javaType, null, modes, IDebugUIConstants.PERSPECTIVE_NONE);
		assertNull("Java debug perspective should now be null", DebugUITools.getLaunchPerspective(javaType, delegate, modes)); //$NON-NLS-1$
		// re-set to default
		DebugUITools.setLaunchPerspective(javaType, null, modes, IDebugUIConstants.PERSPECTIVE_DEFAULT);
		assertEquals("Java debug perspective should now be debug", IDebugUIConstants.ID_DEBUG_PERSPECTIVE, DebugUITools.getLaunchPerspective(javaType, delegate, modes)); //$NON-NLS-1$
	}
	
	/**
	 * Tests that the default run perspective can be over-ridden and reset
	 */
	public void testResetRunLaunchPerspective() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		assertNull("Java run perspective should be null",  //$NON-NLS-1$
			DebugUITools.getLaunchPerspective(javaType, ILaunchManager.RUN_MODE));
		// set to Java perspective
		DebugUITools.setLaunchPerspective(javaType, ILaunchManager.RUN_MODE, JavaUI.ID_PERSPECTIVE);
		assertEquals("Java run perspective should now be java", JavaUI.ID_PERSPECTIVE, //$NON-NLS-1$
					DebugUITools.getLaunchPerspective(javaType, ILaunchManager.RUN_MODE));
		// re-set to default
		DebugUITools.setLaunchPerspective(javaType, ILaunchManager.RUN_MODE, IDebugUIConstants.PERSPECTIVE_DEFAULT);
		assertNull("Java run perspective should now be null",  //$NON-NLS-1$
			DebugUITools.getLaunchPerspective(javaType, ILaunchManager.RUN_MODE));		
	}	
	
	/**
	 * Tests that the default run perspective can be over-ridden and reset.
	 * Same notion as <code>testResetRunLaunchPerspective()</code>, but using the new API
	 * for getting/setting/re-setting perspective settings.
	 * 
	 * @since 3.3
	 */
	public void testResetRunLaunchPerspective2() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		HashSet<String> modes = new HashSet<String>();
		modes.add(ILaunchManager.RUN_MODE);
		assertNull("Java run perspective should be null", DebugUITools.getLaunchPerspective(javaType, null, modes)); //$NON-NLS-1$
		// set to Java perspective
		DebugUITools.setLaunchPerspective(javaType, null, modes, JavaUI.ID_PERSPECTIVE);
		assertEquals("Java run perspective should now be java", JavaUI.ID_PERSPECTIVE, DebugUITools.getLaunchPerspective(javaType, null, modes)); //$NON-NLS-1$
		// re-set to default
		DebugUITools.setLaunchPerspective(javaType, ILaunchManager.RUN_MODE, IDebugUIConstants.PERSPECTIVE_DEFAULT);
		assertNull("Java run perspective should now be null", DebugUITools.getLaunchPerspective(javaType, null, modes));		 //$NON-NLS-1$
	}	
	
	/**
	 * Tests that the default debug perspective can be over-ridden and reset
	 * Same notion as <code>testResetRunLaunchPerspective2()</code>, but using the 
	 * JDT Java launch delegate instead of <code>null</code>
	 * 
	 * @since 3.3
	 */
	public void testResetRunPerspectiveJavaLaunchDelegate() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		HashSet<String> modes = new HashSet<String>();
		modes.add(ILaunchManager.RUN_MODE);
		ILaunchDelegate delegate = ((LaunchManager)getLaunchManager()).getLaunchDelegate("org.eclipse.jdt.launching.localJavaApplication"); //$NON-NLS-1$
		assertNotNull("Java launch delegate should not be null", delegate); //$NON-NLS-1$
		assertNull("Java run perspective should be null", DebugUITools.getLaunchPerspective(javaType, delegate, modes)); //$NON-NLS-1$
		// set to NONE
		DebugUITools.setLaunchPerspective(javaType, null, modes, IDebugUIConstants.PERSPECTIVE_NONE);
		assertNull("Java run perspective should now be null", DebugUITools.getLaunchPerspective(javaType, delegate, modes)); //$NON-NLS-1$
		// re-set to default
		DebugUITools.setLaunchPerspective(javaType, null, modes, IDebugUIConstants.PERSPECTIVE_DEFAULT);
		assertNull("Java run perspective should now be null", DebugUITools.getLaunchPerspective(javaType, delegate, modes)); //$NON-NLS-1$
	}
	
	/**
	 * Tests that the default launch perspective for the 'debug' modeset and java launch delegate is 
	 * <code>ILaunchManager.DEBUG_MODE</code> using the new API.
	 * 
	 * @since 3.3
	 */
	public void testDefaultDebugPerspectiveJavaLaunchDelegate() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		HashSet<String> modes = new HashSet<String>();
		modes.add(ILaunchManager.DEBUG_MODE);
		ILaunchDelegate delegate = ((LaunchManager)getLaunchManager()).getLaunchDelegate("org.eclipse.jdt.launching.localJavaApplication"); //$NON-NLS-1$
		assertNotNull("Java launch delegate should not be null", delegate); //$NON-NLS-1$
		String p = DebugUITools.getLaunchPerspective(javaType, delegate, modes);
		assertEquals("Java debug perspective should be debug", IDebugUIConstants.ID_DEBUG_PERSPECTIVE, p); //$NON-NLS-1$
	}
	
	/**
	 * Tests that the default launch perspective for the 'run' modeset and java launch delegate
	 * is <code>null/code> using the new API
	 * 
	 * @since 3.3
	 */
	public void testDefaultRunPerspectiveJavaLaunchDelegate() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		HashSet<String> modes = new HashSet<String>();
		modes.add(ILaunchManager.RUN_MODE);
		ILaunchDelegate delegate = ((LaunchManager)getLaunchManager()).getLaunchDelegate("org.eclipse.jdt.launching.localJavaApplication"); //$NON-NLS-1$
		assertNotNull("Java launch delegate should not be null", delegate); //$NON-NLS-1$
		String p = DebugUITools.getLaunchPerspective(javaType, delegate, modes);
		assertNull("Java run perspective should be null", p); //$NON-NLS-1$
	}
	
	/**
	 * Tests a perspective contributed with a launch tab group.
	 */
	public void testContributedLaunchPerspective() {
		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		assertEquals("perspective for TEST_MODE should be 'java'", JavaUI.ID_PERSPECTIVE, //$NON-NLS-1$
			DebugUITools.getLaunchPerspective(javaType, "TEST_MODE")); //$NON-NLS-1$
	}
}
