/*******************************************************************************
 * Copyright (c) 2006, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * This is an implementation of an early-draft specification developed under the Java
 * Community Process (JCP) and is made available for testing and evaluation purposes
 * only. The code is not compatible with any specification of the JCP.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *
 *******************************************************************************/
package org.eclipse.jdt.internal.launching.environments;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.internal.launching.EEVMInstall;
import org.eclipse.jdt.internal.launching.EEVMType;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstall2;
import org.eclipse.jdt.launching.IVMInstall3;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.environments.CompatibleEnvironment;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentAnalyzerDelegate;
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
/**
 * Environment analyzer for standard execution environments.
 *
 * @since 3.3
 */
public class ExecutionEnvironmentAnalyzer implements IExecutionEnvironmentAnalyzerDelegate {

	// XXX: Note that this string is not yet standardized by OSGi, see http://wiki.osgi.org/wiki/Execution_Environment

	private static final String JavaSE_14 = "JavaSE-14"; //$NON-NLS-1$
	private static final String JavaSE_13 = "JavaSE-13"; //$NON-NLS-1$
	private static final String JavaSE_12 = "JavaSE-12"; //$NON-NLS-1$
	private static final String JavaSE_11 = "JavaSE-11"; //$NON-NLS-1$
	private static final String JavaSE_10_Plus = "JavaSE-10+"; //$NON-NLS-1$
	private static final String JavaSE_10 = "JavaSE-10"; //$NON-NLS-1$
	static final String JavaSE_9 = "JavaSE-9"; //$NON-NLS-1$
	private static final String JavaSE_1_8 = "JavaSE-1.8"; //$NON-NLS-1$

	private static final String JavaSE_1_7 = "JavaSE-1.7"; //$NON-NLS-1$
	private static final String JavaSE_1_6 = "JavaSE-1.6"; //$NON-NLS-1$
	private static final String J2SE_1_5 = "J2SE-1.5"; //$NON-NLS-1$
	private static final String J2SE_1_4 = "J2SE-1.4"; //$NON-NLS-1$
	private static final String J2SE_1_3 = "J2SE-1.3"; //$NON-NLS-1$
	private static final String J2SE_1_2 = "J2SE-1.2"; //$NON-NLS-1$
	private static final String JRE_1_1 = "JRE-1.1"; //$NON-NLS-1$

	private static final String CDC_FOUNDATION_1_1 = "CDC-1.1/Foundation-1.1"; //$NON-NLS-1$
	private static final String CDC_FOUNDATION_1_0 = "CDC-1.0/Foundation-1.0"; //$NON-NLS-1$

	private static final String OSGI_MINIMUM_1_0 = "OSGi/Minimum-1.0"; //$NON-NLS-1$
	private static final String OSGI_MINIMUM_1_1 = "OSGi/Minimum-1.1"; //$NON-NLS-1$
	private static final String OSGI_MINIMUM_1_2 = "OSGi/Minimum-1.2"; //$NON-NLS-1$

	private static final String JAVA_SPEC_VERSION = "java.specification.version"; //$NON-NLS-1$
	private static final String JAVA_SPEC_NAME = "java.specification.name"; //$NON-NLS-1$
	private static final String JAVA_VERSION = "java.version"; //$NON-NLS-1$

	private static final String[] VM_PROPERTIES = {JAVA_SPEC_NAME, JAVA_SPEC_VERSION, JAVA_VERSION};
	private static final String FOUNDATION = "foundation"; //$NON-NLS-1$
	private static final Map<String, String[]> mappings = new HashMap<>();

	static {
		// table where the key is the EE and the value is an array of EEs that it is a super-set of
		mappings.put(CDC_FOUNDATION_1_0, new String[] {OSGI_MINIMUM_1_0});
		mappings.put(CDC_FOUNDATION_1_1, new String[] {CDC_FOUNDATION_1_0, OSGI_MINIMUM_1_2});
		mappings.put(OSGI_MINIMUM_1_1, new String[] {OSGI_MINIMUM_1_0});
		mappings.put(OSGI_MINIMUM_1_2, new String[] {OSGI_MINIMUM_1_1});
		mappings.put(J2SE_1_2, new String[] {JRE_1_1});
		mappings.put(J2SE_1_3, new String[] {J2SE_1_2, CDC_FOUNDATION_1_0, OSGI_MINIMUM_1_0});
		mappings.put(J2SE_1_4, new String[] {J2SE_1_3, CDC_FOUNDATION_1_1, OSGI_MINIMUM_1_2});
		mappings.put(J2SE_1_5, new String[] {J2SE_1_4});
		mappings.put(JavaSE_1_6, new String[] {J2SE_1_5});
		mappings.put(JavaSE_1_7, new String[] {JavaSE_1_6});
		mappings.put(JavaSE_1_8, new String[] { JavaSE_1_7 });
		mappings.put(JavaSE_9, new String[] { JavaSE_1_8 });
		mappings.put(JavaSE_10, new String[] { JavaSE_9 });
		mappings.put(JavaSE_10_Plus, new String[] { JavaSE_14 });
		mappings.put(JavaSE_11, new String[] { JavaSE_10 });
		mappings.put(JavaSE_12, new String[] { JavaSE_11 });
		mappings.put(JavaSE_13, new String[] { JavaSE_12 });
		mappings.put(JavaSE_14, new String[] { JavaSE_13 });
	}
	@Override
	public CompatibleEnvironment[] analyze(IVMInstall vm, IProgressMonitor monitor) throws CoreException {
		ArrayList<CompatibleEnvironment> result = new ArrayList<>();
		if (!(vm instanceof IVMInstall2)) {
			return new CompatibleEnvironment[0];
		}
		IVMInstall2 vm2 = (IVMInstall2) vm;
		List<String> types = null;
		if (EEVMType.ID_EE_VM_TYPE.equals(vm.getVMInstallType().getId())) {
			String eeId = ((EEVMInstall)vm).getAttribute(EEVMInstall.ATTR_EXECUTION_ENVIRONMENT_ID);
			if (eeId != null) {
				types = getTypes(eeId);
			}
		}
		if (types == null) {
			String javaVersion = vm2.getJavaVersion();
			if (javaVersion == null) {
				// We have a contributed VM type. Check to see if its a foundation VM, if we can.
				if ((vm instanceof IVMInstall3) && isFoundation1_0((IVMInstall3) vm)) {
					types = getTypes(CDC_FOUNDATION_1_0);
				} else if ((vm instanceof IVMInstall3) && isFoundation1_1((IVMInstall3) vm)) {
					types = getTypes(CDC_FOUNDATION_1_1);
				}
			} else {
				if (javaVersion.startsWith("14")) { //$NON-NLS-1$
					types = getTypes(JavaSE_14);
				} else if (javaVersion.startsWith("13")) { //$NON-NLS-1$
					types = getTypes(JavaSE_13);
				} else if (javaVersion.startsWith("12")) { //$NON-NLS-1$
					types = getTypes(JavaSE_12);
				} else if (javaVersion.startsWith("11")) { //$NON-NLS-1$
					types = getTypes(JavaSE_11);
				} else if (javaVersion.startsWith("10")) { //$NON-NLS-1$
					types = getTypes(JavaSE_10);
				} else if (javaVersion.startsWith("9")) { //$NON-NLS-1$
					types = getTypes(JavaSE_9);
				} else if (javaVersion.startsWith("1.8")) { //$NON-NLS-1$
					types = getTypes(JavaSE_1_8);
				} else if (javaVersion.startsWith("1.7")) { //$NON-NLS-1$
					types = getTypes(JavaSE_1_7);
				} else if (javaVersion.startsWith("1.6")) { //$NON-NLS-1$
					types = getTypes(JavaSE_1_6);
				} else if (javaVersion.startsWith("1.5")) { //$NON-NLS-1$
					types = getTypes(J2SE_1_5);
				} else if (javaVersion.startsWith("1.4")) { //$NON-NLS-1$
					types = getTypes(J2SE_1_4);
				} else if (javaVersion.startsWith("1.3")) { //$NON-NLS-1$
					types = getTypes(J2SE_1_3);
				} else if (javaVersion.startsWith("1.2")) { //$NON-NLS-1$
					types = getTypes(J2SE_1_2);
				} else if (javaVersion.startsWith("1.1")) { //$NON-NLS-1$
					if ((vm instanceof IVMInstall3) && isFoundation1_1((IVMInstall3) vm)) {
						types = getTypes(CDC_FOUNDATION_1_1);
					} else {
						types = getTypes(JRE_1_1);
					}
				} else if (javaVersion.startsWith("1.0")) { //$NON-NLS-1$
					if ((vm instanceof IVMInstall3) && isFoundation1_0((IVMInstall3) vm)) {
						types = getTypes(CDC_FOUNDATION_1_0);
					}
				} else if (javaVersion.startsWith("1") && javaVersion.length() >= 2 && javaVersion.charAt(1) != '.') { //$NON-NLS-1$
					// At the moment only caters to versions 11 to 19.
					types = getTypes(JavaSE_10_Plus);
				}
			}
		}

		if (types != null) {
			for (int i=0; i < types.size(); i++) {
				addEnvironment(result, types.get(i), i ==0);
			}
		}
		return result.toArray(new CompatibleEnvironment[result.size()]);
	}

	/*
	 * Check a couple of known system properties for the word "foundation".
	 */
	private boolean isFoundation(Map<String, String> properties) {
		for (int i=0; i < VM_PROPERTIES.length; i++) {
			String value = properties.get(VM_PROPERTIES[i]);
			if (value == null) {
				continue;
			}
			for (StringTokenizer tokenizer = new StringTokenizer(value); tokenizer.hasMoreTokens(); ) {
				if (FOUNDATION.equalsIgnoreCase(tokenizer.nextToken())) {
					return true;
				}
			}
		}
		return false;
	}

	private boolean isFoundation1_0(IVMInstall3 vm) throws CoreException {
		Map<String, String> map = vm.evaluateSystemProperties(VM_PROPERTIES, null);
		return isFoundation(map) ? "1.0".equals(map.get(JAVA_SPEC_VERSION)) : false; //$NON-NLS-1$
	}

	private boolean isFoundation1_1(IVMInstall3 vm) throws CoreException {
		Map<String, String> map = vm.evaluateSystemProperties(VM_PROPERTIES, null);
		return isFoundation(map) ? "1.1".equals(map.get(JAVA_SPEC_VERSION)) : false; //$NON-NLS-1$
	}

	private void addEnvironment(ArrayList<CompatibleEnvironment> result, String id, boolean strict) {
		IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
		IExecutionEnvironment env = manager.getEnvironment(id);
		if (env != null) {
			result.add(new CompatibleEnvironment(env, strict));
		}
	}

	// first entry in the list is the perfect match
	private List<String> getTypes(String type) {
		List<String> result = new ArrayList<>();
		result.add(type);
		String[] values = mappings.get(type);
		if (values != null) {
			for (int i=0; i<values.length; i++) {
				result.addAll(getTypes(values[i]));
			}
		}
		return result;
	}

}
