/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *     Frits Jalvingh - Contribution for Bug 459831 - [launching] Support attaching
 *     	external annotations to a JRE container
 *******************************************************************************/
package org.eclipse.jdt.internal.launching;


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

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.Status;
import org.eclipse.jdt.core.ClasspathContainerInitializer;
import org.eclipse.jdt.core.IClasspathAttribute;
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.launching.IJavaLaunchConfigurationConstants;
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.IExecutionEnvironment;
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
import org.eclipse.osgi.util.NLS;

/**
 * Resolves a container for a JRE classpath container entry.
 */
public class JREContainerInitializer extends ClasspathContainerInitializer {

	/**
	 * @see ClasspathContainerInitializer#initialize(IPath, IJavaProject)
	 */
	@Override
	public void initialize(IPath containerPath, IJavaProject project) throws CoreException {
		if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
			LaunchingPlugin.trace("<JRE_CONTAINER> initialize()"); //$NON-NLS-1$
			LaunchingPlugin.trace("\tPath: " + containerPath.toString()); //$NON-NLS-1$
			LaunchingPlugin.trace("\tProj: " + project.getProject().getName()); //$NON-NLS-1$
		}
		int size = containerPath.segmentCount();
		if (size > 0) {
			if (containerPath.segment(0).equals(JavaRuntime.JRE_CONTAINER)) {
				IVMInstall vm = resolveVM(containerPath);
				JREContainer container = null;
				if (vm != null) {
					if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
						LaunchingPlugin.trace("\tResolved VM: " + vm.getName()); //$NON-NLS-1$
					}
					container = new JREContainer(vm, containerPath, project);
				} else {
					if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
						LaunchingPlugin.trace("\t*** FAILED RESOLVE VM ***"); //$NON-NLS-1$
					}
				}
				JavaCore.setClasspathContainer(containerPath, new IJavaProject[] {project}, new IClasspathContainer[] {container}, null);
			} else {
				if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
					LaunchingPlugin.trace("\t*** INVALID JRE CONTAINER PATH ***"); //$NON-NLS-1$
				}
			}
		} else {
			if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
				LaunchingPlugin.trace("\t*** NO SEGMENTS IN CONTAINER PATH ***"); //$NON-NLS-1$
			}
		}
	}

	/**
	 * Sets the specified class path container for all of the given projects.
	 *
	 * @param containerPath JRE container path
	 * @param projects projects set the container on
	 * @throws CoreException on failure
	 */
	public void initialize(IPath containerPath, IJavaProject[] projects) throws CoreException {
		int size = containerPath.segmentCount();
		if (size > 0) {
			if (containerPath.segment(0).equals(JavaRuntime.JRE_CONTAINER)) {
				int length = projects.length;
				IVMInstall vm = resolveVM(containerPath);
				IClasspathContainer[] containers = new JREContainer[length];
				if (vm != null) {
					if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
						LaunchingPlugin.trace("\tResolved VM: " + vm.getName()); //$NON-NLS-1$
					}
					for (int i=0; i<length; i++) {
						containers[i] = new JREContainer(vm, containerPath, projects[i]);
					}
				} else {
					if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
						LaunchingPlugin.trace("\t*** FAILED RESOLVE VM ***"); //$NON-NLS-1$
					}
				}
				JavaCore.setClasspathContainer(containerPath, projects, containers, null);
			} else {
				if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
					LaunchingPlugin.trace("\t*** INVALID JRE CONTAINER PATH ***"); //$NON-NLS-1$
				}
			}
		} else {
			if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
				LaunchingPlugin.trace("\t*** NO SEGMENTS IN CONTAINER PATH ***"); //$NON-NLS-1$
			}
		}
	}

	/**
	 * Returns the VM install associated with the container path, or <code>null</code>
	 * if it does not exist.
	 * @param containerPath the path to the container
	 * @return the {@link IVMInstall} or <code>null</code>
	 */
	public static IVMInstall resolveVM(IPath containerPath) {
		IVMInstall vm = null;
		if (containerPath.segmentCount() > 1) {
			// specific JRE
			String id = getExecutionEnvironmentId(containerPath);
			if (id != null) {
				if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
					LaunchingPlugin.trace("<JRE_CONTAINER> resolveVM(IPath)"); //$NON-NLS-1$
					LaunchingPlugin.trace("\tEE: " + id); //$NON-NLS-1$
				}
				IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
				IExecutionEnvironment environment = manager.getEnvironment(id);
				if (environment != null) {
					vm = resolveVM(environment);
				} else {
					if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
						LaunchingPlugin.trace("\t*** NO ENVIRONMENT ***"); //$NON-NLS-1$
					}
				}
			} else {
				String vmTypeId = getVMTypeId(containerPath);
				String vmName = getVMName(containerPath);
				IVMInstallType vmType = JavaRuntime.getVMInstallType(vmTypeId);
				if (vmType != null) {
					vm = vmType.findVMInstallByName(vmName);
				}
			}
		} else {
			// workspace default JRE
			vm = JavaRuntime.getDefaultVMInstall();
		}
		return vm;
	}

	/**
	 * Returns the VM install bound to the given execution environment
	 * or <code>null</code>.
	 *
	 * @param environment the environment
	 * @return VM install or <code>null</code>
	 * @since 3.2
	 */
	public static IVMInstall resolveVM(IExecutionEnvironment environment) {
		if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
			LaunchingPlugin.trace("<JRE_CONTAINER> resolveVM(IExecutionEnvironment)"); //$NON-NLS-1$
		}
		IVMInstall vm = environment.getDefaultVM();
		if (vm == null) {
			IVMInstall[] installs = environment.getCompatibleVMs();
			// take the first strictly compatible VM if there is no default
			if (installs.length == 0 && LaunchingPlugin.DEBUG_JRE_CONTAINER) {
				LaunchingPlugin.trace("\t*** NO COMPATIBLE VMS ***"); //$NON-NLS-1$
			}
			for (int i = 0; i < installs.length; i++) {
				IVMInstall install = installs[i];
				if (environment.isStrictlyCompatible(install)) {
					vm = install;
					if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
						LaunchingPlugin.trace("\tPerfect Match: " + vm.getName()); //$NON-NLS-1$
					}
					break;
				}
			}
			//try the default VM install: https://bugs.eclipse.org/bugs/show_bug.cgi?id=371300
			// if default vm is a match https://bugs.eclipse.org/bugs/show_bug.cgi?id=484026
			if (vm == null && installs.length > 0 && Arrays.asList(installs).contains(JavaRuntime.getDefaultVMInstall())) {
				vm = JavaRuntime.getDefaultVMInstall();
			}
			// use the first VM failing that
			if (vm == null && installs.length > 0) {
				vm = installs[0];
				if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
					LaunchingPlugin.trace("\tFirst Match: " + vm.getName()); //$NON-NLS-1$
				}
			}
		} else {
			if (LaunchingPlugin.DEBUG_JRE_CONTAINER) {
				LaunchingPlugin.trace("\tUser Default VM: " + vm.getName()); //$NON-NLS-1$
			}
		}
		return vm;
	}

	/**
	 * Returns the segment from the path containing the execution environment id
	 * or <code>null</code>
	 *
	 * @param path container path
	 * @return EE id
	 */
	public static String getExecutionEnvironmentId(IPath path) {
		String name = getVMName(path);
		if (name != null) {
			name = decodeEnvironmentId(name);
			IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
			IExecutionEnvironment environment = manager.getEnvironment(name);
			if (environment != null) {
				return environment.getId();
			}
		}
		return null;
	}

	/**
	 * Returns whether the given path identifies a VM by execution environment.
	 *
	 * @param path the path
	 * @return whether the given path identifies a VM by execution environment
	 */
	public static boolean isExecutionEnvironment(IPath path) {
		return getExecutionEnvironmentId(path) != null;
	}

	/**
	 * Escapes forward slashes in environment id.
	 *
	 * @param id the environment id
	 * @return escaped name
	 */
	public static String encodeEnvironmentId(String id) {
		return id.replace('/', '%');
	}

	public static String decodeEnvironmentId(String id) {
		return id.replace('%', '/');
	}

	/**
	 * Returns the VM type identifier from the given container ID path.
	 *
	 * @param path the path
	 * @return the VM type identifier from the given container ID path
	 */
	public static String getVMTypeId(IPath path) {
		return path.segment(1);
	}

	/**
	 * Returns the VM name from the given container ID path.
	 *
	 * @param path the path
	 * @return the VM name from the given container ID path
	 */
	public static String getVMName(IPath path) {
		return path.segment(2);
	}

	/**
	 * The container can be updated if it refers to an existing VM.
	 *
	 * @see org.eclipse.jdt.core.ClasspathContainerInitializer#canUpdateClasspathContainer(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject)
	 */
	@Override
	public boolean canUpdateClasspathContainer(IPath containerPath, IJavaProject project) {
		if (containerPath != null && containerPath.segmentCount() > 0) {
			if (JavaRuntime.JRE_CONTAINER.equals(containerPath.segment(0))) {
				return resolveVM(containerPath) != null;
			}
		}
		return false;
	}

	private static final IStatus READ_ONLY= new Status(IStatus.ERROR, LaunchingPlugin.ID_PLUGIN, ClasspathContainerInitializer.ATTRIBUTE_READ_ONLY, new String(), null);
	private static final IStatus NOT_SUPPORTED= new Status(IStatus.ERROR, LaunchingPlugin.ID_PLUGIN, ClasspathContainerInitializer.ATTRIBUTE_NOT_SUPPORTED, new String(), null);

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.ClasspathContainerInitializer#getAccessRulesStatus(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject)
	 */
	@Override
	public IStatus getAccessRulesStatus(IPath containerPath, IJavaProject project) {
		return READ_ONLY;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.ClasspathContainerInitializer#getSourceAttachmentStatus(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject)
	 */
	@Override
	public IStatus getSourceAttachmentStatus(IPath containerPath, IJavaProject project) {
		return Status.OK_STATUS;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.ClasspathContainerInitializer#getAttributeStatus(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject, java.lang.String)
	 */
	@Override
	public IStatus getAttributeStatus(IPath containerPath, IJavaProject project, String attributeKey) {
		if (attributeKey.equals(IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME)) {
			return Status.OK_STATUS;
		}
		if (attributeKey.equals(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH)) {
			return Status.OK_STATUS;
		}
		if (attributeKey.equals(JavaRuntime.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY)) {
			return Status.OK_STATUS;
		}
		return NOT_SUPPORTED;
	}

	/**
	 * @see org.eclipse.jdt.core.ClasspathContainerInitializer#requestClasspathContainerUpdate(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject, org.eclipse.jdt.core.IClasspathContainer)
	 */
	@Override
	public void requestClasspathContainerUpdate(IPath containerPath, IJavaProject project, IClasspathContainer containerSuggestion) throws CoreException {
		IVMInstall vm = resolveVM(containerPath);
		if (vm == null) {
			IStatus status = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_VM_INSTALL_DOES_NOT_EXIST, NLS.bind(LaunchingMessages.JREContainerInitializer_JRE_referenced_by_classpath_container__0__does_not_exist__1, new String[]{containerPath.toString()}), null);
			throw new CoreException(status);
		}
		// update of the VM with new library locations

		IClasspathEntry[] entries = containerSuggestion.getClasspathEntries();
		LibraryLocation[] libs = new LibraryLocation[entries.length];
		for (int i = 0; i < entries.length; i++) {
			IClasspathEntry entry = entries[i];
			if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
				IPath path = entry.getPath();
				File lib = path.toFile();
				if (lib.exists() && lib.isFile()) {
					IPath srcPath = entry.getSourceAttachmentPath();
					if (srcPath == null) {
						srcPath = Path.EMPTY;
					}
					IPath rootPath = entry.getSourceAttachmentRootPath();
					if (rootPath == null) {
						rootPath = Path.EMPTY;
					}
					URL javadocLocation = null;
					IPath externalAnnotations = null;
					IClasspathAttribute[] extraAttributes = entry.getExtraAttributes();
					for (int j = 0; j < extraAttributes.length; j++) {
						IClasspathAttribute attribute = extraAttributes[j];
						if (attribute.getName().equals(IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME)) {
							String url = attribute.getValue();
							if (url != null && url.trim().length() > 0) {
								try {
									javadocLocation = new URL(url);
								} catch (MalformedURLException e) {
									LaunchingPlugin.log(e);
								}
							}
						} else if (attribute.getName().equals(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH)) {
							String xpath = attribute.getValue();
							if (null != xpath && xpath.trim().length() > 0) {
								try {
									externalAnnotations = Path.fromPortableString(xpath);
								} catch (Exception x) {
									LaunchingPlugin.log(x);
								}
							}
						}
					}
					libs[i] = new LibraryLocation(path, srcPath, rootPath, javadocLocation, null, externalAnnotations);
				} else {
					IStatus status = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR, NLS.bind(LaunchingMessages.JREContainerInitializer_Classpath_entry__0__does_not_refer_to_an_existing_library__2, new String[]{entry.getPath().toString()}), null);
					throw new CoreException(status);
				}
			} else {
				IStatus status = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR, NLS.bind(LaunchingMessages.JREContainerInitializer_Classpath_entry__0__does_not_refer_to_a_library__3, new String[]{entry.getPath().toString()}), null);
				throw new CoreException(status);
			}
		}
		VMStandin standin = new VMStandin(vm);
		standin.setLibraryLocations(libs);
		standin.convertToRealVM();
		JavaRuntime.saveVMConfiguration();
	}

	/**
	 * @see org.eclipse.jdt.core.ClasspathContainerInitializer#getDescription(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject)
	 */
	@Override
	public String getDescription(IPath containerPath, IJavaProject project) {
		String tag = getExecutionEnvironmentId(containerPath);
		if (tag == null && containerPath.segmentCount() > 2) {
			tag = getVMName(containerPath);
		}
		if (tag != null) {
			return NLS.bind(LaunchingMessages.JREContainer_JRE_System_Library_1, new String[]{tag});
		}
		return LaunchingMessages.JREContainerInitializer_Default_System_Library_1;
	}
}
