/*******************************************************************************
 * 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 org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchDelegate;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.debug.core.sourcelookup.ISourcePathComputer;
import org.eclipse.jdt.debug.testplugin.AlternateDelegate;
import org.eclipse.jdt.debug.testplugin.launching.TestLaunchDelegate1;
import org.eclipse.jdt.debug.testplugin.launching.TestLaunchDelegate2;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;

/**
 * Tests for launch delegates
 */
public class LaunchDelegateTests extends AbstractDebugTest {
	
	/**
	 * Constructor
	 * @param name
	 */
	public LaunchDelegateTests(String name) {
		super(name);
	}
	
	/**
	 * Ensures a launch delegate can provide a launch object for
	 * a launch.
	 * @throws CoreException
	 */
	public void testProvideLaunch() throws CoreException {
		ILaunchManager manager = getLaunchManager();
		ILaunchConfigurationType configurationType = manager.getLaunchConfigurationType("org.eclipse.jdt.debug.tests.testConfigType"); //$NON-NLS-1$
		assertNotNull("Missing test launch config type", configurationType); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy workingCopy = configurationType.newInstance(null, "provide-launch-object"); //$NON-NLS-1$
		// delegate will throw exception if test fails
		ILaunch launch = workingCopy.launch(ILaunchManager.DEBUG_MODE, null);
		manager.removeLaunch(launch);
	}
	
	/**
	 * Tests that a delegate extension can provide the source path computer.
	 */
	public void testSourcePathComputerExtension() {
		ILaunchManager manager = getLaunchManager();
		ILaunchConfigurationType configurationType = manager.getLaunchConfigurationType("org.eclipse.jdt.debug.tests.testConfigType"); //$NON-NLS-1$
		assertNotNull("Missing test launch config type", configurationType); //$NON-NLS-1$
		ISourcePathComputer sourcePathComputer = configurationType.getSourcePathComputer();
		assertEquals("Wrong source path computer", "org.eclipse.jdt.debug.tests.testSourcePathComputer", sourcePathComputer.getId()); //$NON-NLS-1$ //$NON-NLS-2$
	}
	
	/**
	 * Tests that a delegate extension can provide the source locator.
	 */
	public void testSourceLocatorExtension() {
		ILaunchManager manager = getLaunchManager();
		ILaunchConfigurationType configurationType = manager.getLaunchConfigurationType("org.eclipse.jdt.debug.tests.testConfigType"); //$NON-NLS-1$
		assertNotNull("Missing test launch config type", configurationType); //$NON-NLS-1$
		String sourceLocatorId = configurationType.getSourceLocatorId();
		assertEquals("Wrong source locater id", "org.eclipse.jdt.debug.tests.testSourceLocator", sourceLocatorId); //$NON-NLS-1$ //$NON-NLS-2$
	}
	
	/**
	 * Test launch delegate for mixed launch mode.
	 * @throws CoreException 
	 */
	public void testMixedModeDelegate() throws CoreException {
		ILaunchManager manager = getLaunchManager();
		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		assertNotNull("Missing java application launch config type", type); //$NON-NLS-1$
		HashSet<String> modes = new HashSet<String>();
		modes.add("alternate"); //$NON-NLS-1$
		modes.add(ILaunchManager.DEBUG_MODE);
		assertTrue("Should support mixed mode (alternate/debug)", type.supportsModeCombination(modes)); //$NON-NLS-1$
		ILaunchDelegate[] delegates = type.getDelegates(modes);
		assertTrue("missing delegate", delegates.length > 0); //$NON-NLS-1$
		assertEquals("Wrong number of delegates", 1, delegates.length); //$NON-NLS-1$
		assertTrue("Wrong delegate", delegates[0].getDelegate() instanceof AlternateDelegate); //$NON-NLS-1$
	}
	
	/**
	 * Tests if the java launch delegate was found as one of the delegates for debug mode.
	 * @throws CoreException
	 */
	public void testSingleDebugModeDelegate() throws CoreException {
		ILaunchManager manager = getLaunchManager();
		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		assertNotNull("Missing java application launch config type", type); //$NON-NLS-1$
		HashSet<String> modes = new HashSet<String>();
		modes.add(ILaunchManager.DEBUG_MODE);
		assertTrue("Should support mode (debug)", type.supportsModeCombination(modes)); //$NON-NLS-1$
		ILaunchDelegate[] delegates = type.getDelegates(modes);
		assertTrue("missing delegate", delegates.length > 0); //$NON-NLS-1$
		boolean found = false;
		for(int i = 0; i < delegates.length; i++) {
			if(delegates[i].getDelegate().getClass().getName().endsWith("JavaLaunchDelegate")) { //$NON-NLS-1$
				found = true;
				break;
			}
		}
		assertTrue("The java launch delegate was not one of the returned delegates", found);		 //$NON-NLS-1$
	}
	
	/**
	 * Tests correct delegate is found for alternate mode.
	 * @throws CoreException
	 */
	public void testSingleAlternateModeDelegate() throws CoreException {
		ILaunchManager manager = getLaunchManager();
		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		assertNotNull("Missing java application launch config type", type); //$NON-NLS-1$
		HashSet<String> modes = new HashSet<String>();
		modes.add("alternate"); //$NON-NLS-1$
		assertTrue("Should support mode (alternate)", type.supportsModeCombination(modes)); //$NON-NLS-1$
		ILaunchDelegate[] delegates = type.getDelegates(modes);
		assertTrue("missing delegate", delegates.length > 0); //$NON-NLS-1$
		assertEquals("Wrong number of delegates", 1, delegates.length); //$NON-NLS-1$
		assertTrue("Wrong delegate", delegates[0].getDelegate() instanceof AlternateDelegate);		 //$NON-NLS-1$
	}	
	
	/**
	 * Checks that the delegate definition is collecting and parsing mode combination information properly from both the delegate
	 * contribution and from modeCombination child elements
	 * @throws CoreException
	 */
	public void testMultipleModeSingleDelegate() throws CoreException {
		ILaunchManager manager = getLaunchManager();
		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		assertNotNull("Missing java application launch config type", type); //$NON-NLS-1$
		String[][] modesavail = {{"alternate"}, {"debug", "alternate"}, {"debug", "alternate2"}}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
		HashSet<String> modes = null;
		for(int i = 0; i < modesavail.length; i++) {
			modes = new HashSet<String>(Arrays.asList(modesavail[i]));
			assertTrue("Should support modes "+modes.toString(), type.supportsModeCombination(modes)); //$NON-NLS-1$
			ILaunchDelegate[] delegates = type.getDelegates(modes);
			assertTrue("missing delegate", delegates.length > 0); //$NON-NLS-1$
			assertEquals("Wrong number of delegates", 1, delegates.length); //$NON-NLS-1$
			assertTrue("Wrong delegate", delegates[0].getDelegate() instanceof AlternateDelegate);	 //$NON-NLS-1$
		}
	}
	
	/**
	 * Checks that all applicable delegates are found for given types and mode combinations
	 * @throws CoreException
	 */
	public void testSingleModeMultipleDelegates() throws CoreException {
		ILaunchManager manager = getLaunchManager();
		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		assertNotNull("Missing java application launch config type", type); //$NON-NLS-1$
		HashSet<String> modes = new HashSet<String>();
		modes.add("alternate2"); //$NON-NLS-1$
		assertTrue("Should support mode 'alternate2'", type.supportsModeCombination(modes)); //$NON-NLS-1$
		ILaunchDelegate[] delegates = type.getDelegates(modes);
		assertTrue("missing delegate", delegates.length > 0); //$NON-NLS-1$
		assertEquals("Wrong number of delegates, should be 2 only "+delegates.length+" found", 2, delegates.length); //$NON-NLS-1$ //$NON-NLS-2$
		HashSet<Class<? extends ILaunchConfigurationDelegate>> dels = new HashSet<Class<? extends ILaunchConfigurationDelegate>>();
		for(int i = 0; i < delegates.length; i++) {
			dels.add(delegates[i].getDelegate().getClass());
		}
		HashSet<Object> ds = new HashSet<Object>(Arrays.asList(new Object[] {TestLaunchDelegate1.class, TestLaunchDelegate2.class}));
		assertTrue("There must be only TestLaunchDelegate1 and TestLaunchDelegate2 as registered delegates for the mode alternate2 and the local java type", ds.containsAll(dels)); //$NON-NLS-1$
	}
	
	/**
	 * Checks to see the even with a partial match of a mode combination it will indicate that it does not support the specified modes
	 */
	public void testPartialModeCombination() {
		ILaunchManager manager = getLaunchManager();
		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		assertNotNull("Missing java application launch config type", type); //$NON-NLS-1$
		HashSet<String> modes = new HashSet<String>();
		modes.add("alternate2"); //$NON-NLS-1$
		modes.add("foo"); //$NON-NLS-1$
		assertTrue("Should not support modes: "+modes.toString(), !type.supportsModeCombination(modes)); //$NON-NLS-1$
	}
}
