/*******************************************************************************
 * Copyright (c) 2007, 2013 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
 *     Jesper S Moller - Bug 421938: [1.8] ExecutionEnvironmentDescription#getVMArguments does not preserve VM arguments
 *******************************************************************************/
package org.eclipse.jdt.debug.tests.core;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.debug.testplugin.JavaTestPlugin;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.internal.launching.EEVMType;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.LibraryLocation;
import org.eclipse.jdt.launching.VMStandin;
import org.eclipse.jdt.launching.environments.ExecutionEnvironmentDescription;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;

/**
 * Tests for ".ee" files - installed JRE definition files
 */
public class EEDefinitionTests extends AbstractDebugTest {

	public static IPath TEST_EE_FILE = null;
	{
		if (Platform.OS_WIN32.equals(Platform.getOS())) {
			TEST_EE_FILE = new Path("testfiles/test-jre/bin/test-foundation11-win32.ee");
		} else {
			TEST_EE_FILE = new Path("testfiles/test-jre/bin/test-foundation11.ee");
		}
	}

	public EEDefinitionTests(String name) {
		super(name);
	}

	/**
	 * Tests that the EE file is a valid file
	 */
	public void testValidateDefinitionFile() throws CoreException {
		File file = getEEFile();
		assertNotNull("Missing EE file", file);
		ExecutionEnvironmentDescription description = new ExecutionEnvironmentDescription(file);
		IStatus status = EEVMType.validateDefinitionFile(description);
		assertTrue("Invalid install location", status.isOK());
	}

	/**
	 * Tests that the EE install location validation returns an INFO status.
	 */
	public void testValidateInstallLocation() {
		File file = getEEFile();
		IVMInstallType vmType = getVMInstallType();
		assertNotNull("Missing EE file", file);
		assertNotNull("Missing EE VM type", vmType);
		IStatus status = vmType.validateInstallLocation(file);
		assertTrue("Invalid install location", status.getSeverity() == IStatus.INFO);
	}

	/**
	 * Tests libraries for the EE file
	 */
	public void testLibraries() throws CoreException {
		File file = getEEFile();
		assertNotNull("Missing EE file", file);
		ExecutionEnvironmentDescription description = new ExecutionEnvironmentDescription(file);
		LibraryLocation[] libs = description.getLibraryLocations();
		String[] expected = new String[]{"end.jar", "classes.txt", "others.txt", "add.jar", "ext1.jar", "ext2.jar", "opt-ext.jar"};
		assertEquals("Wrong number of libraries", expected.length, libs.length);
		for (int i = 0; i < expected.length; i++) {
			if (i == 4) {
				// ext1 and ext2 can be in either order due to file system ordering
				assertTrue("Wrong library", expected[i].equals(libs[i].getSystemLibraryPath().lastSegment()) ||
						expected[i].equals(libs[i+1].getSystemLibraryPath().lastSegment()));
			} else if (i == 5) {
				// ext1 and ext2 can be in either order due to file system ordering
				assertTrue("Wrong library", expected[i].equals(libs[i].getSystemLibraryPath().lastSegment()) ||
						expected[i].equals(libs[i-1].getSystemLibraryPath().lastSegment()));
			} else {
				assertEquals("Wrong library", expected[i], libs[i].getSystemLibraryPath().lastSegment());
			}
			if ("classes.txt".equals(expected[i])) {
				assertEquals("source.txt", libs[i].getSystemLibrarySourcePath().lastSegment());
			}
		}
	}

	/**
	 * Tests source attachments
	 */
	public void testSourceAttachments() throws CoreException {
		File file = getEEFile();
		assertNotNull("Missing EE file", file);
		ExecutionEnvironmentDescription description = new ExecutionEnvironmentDescription(file);
		LibraryLocation[] libs = description.getLibraryLocations();
		String[] expected = new String[]{"end.txt", "source.txt", "source.txt", "sourceaddsource.jar", "extra1-src.txt", "extra2-src.txt", ""};
		assertEquals("Wrong number of libraries", expected.length, libs.length);
		for (int i = 0; i < expected.length; i++) {
			if (i == 4) {
				// ext1 and ext2 can be in either order due to file system ordering
				assertTrue("Wrong attachment", expected[i].equals(libs[i].getSystemLibrarySourcePath().lastSegment()) ||
						expected[i].equals(libs[i+1].getSystemLibrarySourcePath().lastSegment()));
			} else if (i == 5) {
				// ext1 and ext2 can be in either order due to file system ordering
				assertTrue("Wrong attachment", expected[i].equals(libs[i].getSystemLibrarySourcePath().lastSegment()) ||
						expected[i].equals(libs[i-1].getSystemLibrarySourcePath().lastSegment()));
			} else if (i == 6){
				assertEquals("Wrong attachment", Path.EMPTY, libs[i].getSystemLibrarySourcePath());
			} else {
				assertEquals("Wrong attachment", expected[i], libs[i].getSystemLibrarySourcePath().lastSegment());
			}
		}
	}

	/**
	 * Tests default libraries for an EE VM type are empty.
	 */
	public void testDefaultLibraries() {
		File file = getEEFile();
		IVMInstallType vmType = getVMInstallType();
		assertNotNull("Missing EE file", file);
		assertNotNull("Missing EE VM type", vmType);
		LibraryLocation[] libs = vmType.getDefaultLibraryLocations(file);
		assertEquals("Wrong number of libraries", 0, libs.length);
	}

	/**
	 * Tests that a javadoc location can be specified.
	 */
	public void testJavadocLocation() throws CoreException {
		File file = getEEFile();
		assertNotNull("Missing EE file", file);
		ExecutionEnvironmentDescription ee = new ExecutionEnvironmentDescription(file);
		URL location = EEVMType.getJavadocLocation(ee.getProperties());
		URL expectedLocation = null;
		try {
			expectedLocation = new URL("http://a.javadoc.location");
		} catch (MalformedURLException e) {
			fail();
		}
		assertEquals("Incorrect javadoc location", expectedLocation, location);
	}

	/**
	 * Tests asking for the index from the EE file
	 *
	 * @throws Exception
	 * @since 3.9.0
	 */
	public void testIndexLocation() throws Exception {
		File file = getEEFile();
		assertNotNull("Missing EE file", file);
		ExecutionEnvironmentDescription ee = new ExecutionEnvironmentDescription(file);
		URL location = EEVMType.getIndexLocation(ee.getProperties());
		URL expectedLocation = null;
		try {
			expectedLocation = new URL("http://a.index.location");
		} catch (MalformedURLException e) {
			fail();
		}
		assertEquals("Incorrect index location", expectedLocation, location);
	}

	/**
	 * Tests that a name with spaces can be specified.
	 */
	public void testVMName() throws CoreException {
		File file = getEEFile();
		assertNotNull("Missing EE file", file);
		ExecutionEnvironmentDescription ee = new ExecutionEnvironmentDescription(file);
		String name = ee.getProperty(ExecutionEnvironmentDescription.EE_NAME);
		assertEquals("Incorrect vm name", "Eclipse JDT Test JRE Definition", name);
	}

	/**
	 * Tests default VM arguments. All arguments from the EE file should get passed through in the
	 * same order to the command line.
	 */
	public void testVMArguments() throws CoreException {
		File file = getEEFile();
		assertNotNull("Missing EE file", file);
		ExecutionEnvironmentDescription description = new ExecutionEnvironmentDescription(file);
		String defaultVMArguments = description.getVMArguments();
		String[] expected = new String[] {
				"-XspecialArg:123",
				"-XspecialArg2=456",
				"-XspecialArg3=789"
		};
		int prev = -1;
		for (int i = 0; i < expected.length; i++) {
			int next = defaultVMArguments.indexOf(expected[i]);
			assertTrue("Missing argument: " + expected[i] + ": was: " + defaultVMArguments,  next >= 0);
			assertTrue("Wrong argument order: " + expected[i] + ": " + defaultVMArguments,  next > prev);
			prev = next;
		}
	}

	/**
	 * Test compatible environments
	 */
	public void testCompatibleEEs() throws CoreException {
		IVMInstall install = null;
		EEVMType vmType = (EEVMType) getVMInstallType();
		try {
			File file = getEEFile();
			assertNotNull("Missing EE file", file);
			assertNotNull("Missing EE VM type", vmType);
			VMStandin standin = JavaRuntime.createVMFromDefinitionFile(file, "test-ee-file", "test-ee-file-id");
			install = standin.convertToRealVM();

			IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
			IExecutionEnvironment[] envs = manager.getExecutionEnvironments();
			boolean found11 = false;
			for (int i = 0; i < envs.length; i++) {
				IExecutionEnvironment env = envs[i];
				if (env.getId().equals("CDC-1.1/Foundation-1.1")) {
					found11 = true;
					assertTrue("Should be strictly compatible with " + env.getId(), env.isStrictlyCompatible(install));
				} else if (env.getId().indexOf("jdt.debug.tests") < 0) {
					assertFalse("Should *not* be strictly compatible with " + env.getId(), env.isStrictlyCompatible(install));
				}
			}
			assertTrue("Did not find foundation 1.1 environment", found11);
		} finally {
			if (install != null && vmType != null) {
				vmType.disposeVMInstall(install.getId());
			}
		}
	}

	protected File getEEFile() {
		return JavaTestPlugin.getDefault().getFileInPlugin(TEST_EE_FILE);
	}

	protected IVMInstallType getVMInstallType() {
		return JavaRuntime.getVMInstallType(EEVMType.ID_EE_VM_TYPE);
	}

	/**
	 * Tests raw EE properties map.
	 *
	 * @throws CoreException
	 */
	public void testParseProperties() throws CoreException {
		File file = getEEFile();
		assertNotNull("Missing EE file", file);
		ExecutionEnvironmentDescription desc = new ExecutionEnvironmentDescription(file);
		Map<String, String> map = desc.getProperties();

		// validate expected properties
		validateProperty(ExecutionEnvironmentDescription.EXECUTABLE, "jrew.txt" , map);
		validateProperty(ExecutionEnvironmentDescription.EXECUTABLE_CONSOLE, "jre.txt", map);
		validateProperty("-XspecialArg:123", "", map);
		validateProperty("-XspecialArg2", "456", map);

	}

	protected void validateProperty(String key, String value, Map<String, String> properties) {
		assertEquals("Unexpeted value for: " + key, value, properties.get(key));
	}

	/**
	 * Tests that a name with spaces can be specified.
	 */
	public void testEmptyProperty() throws CoreException {
		File file = getEEFile();
		assertNotNull("Missing EE file", file);
		ExecutionEnvironmentDescription ee = new ExecutionEnvironmentDescription(file);
		validateProperty("-Dee.empty", "", ee.getProperties());
	}
}
