/*******************************************************************************
 * Copyright (c) 2000, 2011 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.core;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.debug.testplugin.JavaProjectHelper;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.LibraryLocation;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;

/**
 * Tests for execution environments
 */
public class ExecutionEnvironmentTests extends AbstractDebugTest {
		
	public ExecutionEnvironmentTests(String name) {
		super(name);
	}
	
	public void testGetEnvironments() throws Exception {
		IExecutionEnvironment[] executionEnvironments = JavaRuntime.getExecutionEnvironmentsManager().getExecutionEnvironments();
		assertTrue("Should be at least one environment", executionEnvironments.length > 0);
		for (int i = 0; i < executionEnvironments.length; i++) {
			IExecutionEnvironment environment = executionEnvironments[i];
			if (environment.getId().equals(JavaProjectHelper.J2SE_1_4_EE_NAME)) {
				return;
			}
		}
		assertTrue("Did not find environment J2SE-1.4", false);
	}
	
	public void testAnalyze() throws Exception {
		IVMInstall vm = JavaRuntime.getDefaultVMInstall();
		IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
				
		IExecutionEnvironment environment = manager.getEnvironment(JavaProjectHelper.J2SE_1_4_EE_NAME);
		assertNotNull("Missing environment J2SE-1.4", environment);
		IVMInstall[] installs = environment.getCompatibleVMs();
		assertTrue("Should be at least one vm install for the environment", installs.length > 0);
		for (int i = 0; i < installs.length; i++) {
			IVMInstall install = installs[i];
			if (install.equals(vm)) {
				return;
			}
		}
		assertTrue("vm should be J2SE-1.4 compliant", false);
	}
	
	public void testAccessRuleParticipants() throws Exception {
		IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
		IExecutionEnvironment environment = manager.getEnvironment("org.eclipse.jdt.debug.tests.environment.j2se14x");
		assertNotNull("Missing environment j2se14x", environment);
		IVMInstall vm = JavaRuntime.getDefaultVMInstall();
		LibraryLocation[] libraries = JavaRuntime.getLibraryLocations(vm);
		IAccessRule[][] accessRules = environment.getAccessRules(vm, libraries, get14Project());
		assertNotNull("Missing access rules", accessRules);
		assertEquals("Wrong number of rules", libraries.length, accessRules.length);
		for (int i = 0; i < accessRules.length; i++) {
			IAccessRule[] rules = accessRules[i];
			assertEquals("wrong number of rules for lib", 4, rules.length);
			assertEquals("Wrong rule", "secondary", rules[0].getPattern().toString());
			assertEquals("Wrong rule", "discouraged", rules[1].getPattern().toString());
			assertEquals("Wrong rule", "accessible", rules[2].getPattern().toString());
			assertEquals("Wrong rule", "non_accessible", rules[3].getPattern().toString());
		}
	}
	
	public void testNoAccessRuleParticipants() throws Exception {
		IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
		IExecutionEnvironment environment = manager.getEnvironment("org.eclipse.jdt.debug.tests.environment.j2se13x");
		assertNotNull("Missing environment j2se13x", environment);
		IVMInstall vm = JavaRuntime.getDefaultVMInstall();
		LibraryLocation[] libraries = JavaRuntime.getLibraryLocations(vm);
		IAccessRule[][] accessRules = environment.getAccessRules(vm, libraries, get14Project());
		assertNotNull("Missing access rules", accessRules);
		assertEquals("Wrong number of rules", libraries.length, accessRules.length);
		for (int i = 0; i < accessRules.length; i++) {
			IAccessRule[] rules = accessRules[i];
			assertEquals("wrong number of rules for lib", 0, rules.length);
		}
	}	
	
	public void testAccessRuleParticipantsWithShortCircut() throws Exception {
		IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
		IExecutionEnvironment environment = manager.getEnvironment("org.eclipse.jdt.debug.tests.environment.j2se15x");
		assertNotNull("Missing environment j2se15x", environment);
		IVMInstall vm = JavaRuntime.getDefaultVMInstall();
		LibraryLocation[] libraries = JavaRuntime.getLibraryLocations(vm);
		IAccessRule[][] accessRules = environment.getAccessRules(vm, libraries, get14Project());
		assertNotNull("Missing access rules", accessRules);
		assertEquals("Wrong number of rules", libraries.length, accessRules.length);
		for (int i = 0; i < accessRules.length; i++) {
			IAccessRule[] rules = accessRules[i];
			assertEquals("wrong number of rules for lib", 1, rules.length);
			assertEquals("Wrong rule", "**/*", rules[0].getPattern().toString());
		}
	}
	
	/**
	 * Tests that a project bound to an EE has access rules.
	 */
	public void testAccessRulesPresentOnEEProject() throws Exception {
		boolean foundLib = false;
		IJavaProject project = getBoundEeProject();
		assertTrue("BoundEE project does not exist", project.exists());
		IClasspathEntry[] rawClasspath = project.getRawClasspath();
		for (int i = 0; i < rawClasspath.length; i++) {
			IClasspathEntry entry = rawClasspath[i];
			if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
				String environmentId = JavaRuntime.getExecutionEnvironmentId(entry.getPath());
				if (environmentId != null) {
					IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), project);
					assertNotNull("missing classpath container", container);
					IClasspathEntry[] entries = container.getClasspathEntries();
					for (int j = 0; j < entries.length; j++) {
						foundLib = true;
						IClasspathEntry containerEntry = entries[j];
						assertTrue("Missing access rules", containerEntry.getAccessRules().length > 0);
					}
				}
			}
		}
		assertTrue("did not find JRE libs on classpath", foundLib);
	}
	
	/**
	 * Tests that a project bound to a specific JRE has no access rules.
	 */
	public void testAccessRulesNotPresentOnJREProject() throws Exception {
		boolean foundLib = false;
		IJavaProject project = getBoundJreProject();
		assertTrue("BoundJRE project does not exist", project.exists());
		IClasspathEntry[] rawClasspath = project.getRawClasspath();
		for (int i = 0; i < rawClasspath.length; i++) {
			IClasspathEntry entry = rawClasspath[i];
			if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
				IVMInstall install = JavaRuntime.getVMInstall(entry.getPath());
				if (install != null) {
					IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), project);
					assertNotNull("missing classpath container", container);
					IClasspathEntry[] entries = container.getClasspathEntries();
					for (int j = 0; j < entries.length; j++) {
						foundLib = true;
						IClasspathEntry containerEntry = entries[j];
						assertEquals("access rules should not be present", 0, containerEntry.getAccessRules().length);
					}
				}
			}
		}
		assertTrue("did not find JRE library on classpath", foundLib);		
	}	
	
	/**
	 * Tests that default access rules appear for system packages when a profile file is specified.
	 * 
	 * @throws Exception
	 */
	public void testDefaultSystemPackageAccessRules() throws Exception {
		IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
		IExecutionEnvironment environment = manager.getEnvironment("org.eclipse.jdt.debug.tests.systemPackages");
		assertNotNull("Missing environment systemPackages", environment);
		IVMInstall vm = JavaRuntime.getDefaultVMInstall();
		LibraryLocation[] libraries = JavaRuntime.getLibraryLocations(vm);
		IAccessRule[][] accessRules = environment.getAccessRules(vm, libraries, get14Project());
		assertNotNull("Missing access rules", accessRules);
		assertEquals("Wrong number of rules", libraries.length, accessRules.length);
		for (int i = 0; i < accessRules.length; i++) {
			IAccessRule[] rules = accessRules[i];
			assertEquals("wrong number of rules for lib", 4, rules.length);
			assertEquals("Wrong rule", "java/**", rules[0].getPattern().toString());
			assertEquals("Wrong rule", "one/two/*", rules[1].getPattern().toString());
			assertEquals("Wrong rule", "three/four/*", rules[2].getPattern().toString());
			assertEquals("Wrong rule", "**/*", rules[3].getPattern().toString());
		}		
	}
	
	/**
	 * Tests that a location can be resolved for ${ee_home:J2SE-1.4}
	 * 
	 * @throws Exception
	 */
	public void testEEHomeVariable() throws Exception {
		IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
		String result = manager.performStringSubstitution("${ee_home:J2SE-1.4}");
		assertNotNull(result);
		IExecutionEnvironment ee = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(JavaProjectHelper.J2SE_1_4_EE_NAME);
		IVMInstall install = JavaRuntime.getVMInstall(JavaRuntime.newJREContainerPath(ee));
		assertEquals(install.getInstallLocation().getAbsolutePath(), result);
	}
	
	/**
	 * Tests that a location cannot be resolved for ${ee_home}
	 * 
	 * @throws Exception
	 */
	public void testEEHomeVariableMissingArgument() throws Exception {
		IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
		try {
			manager.performStringSubstitution("${ee_home}");
		} catch (CoreException e) {
			return; // expected
		}
		assertNotNull("Test should have thrown an exception", null);
	}
	
	/**
	 * Tests that a location cannot be resolved for ${ee_home:bogus}
	 * 
	 * @throws Exception
	 */
	public void testEEHomeVariableInvalidArgument() throws Exception {
		IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
		try {
			manager.performStringSubstitution("${ee_home:bogus}");
		} catch (CoreException e) {
			return; // expected
		}
		assertNotNull("Test should have thrown an exception", null);
	}	
}
