/*******************************************************************************
 * Copyright (c) 2000, 2013 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/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Jeff Myers myersj@gmail.com - fix for #75201
 *     Ralf Ebert ralf@ralfebert.de - fix for #307109
 *******************************************************************************/
package org.eclipse.jdt.internal.launching.macosx;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

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.internal.launching.LaunchingPlugin;
import org.eclipse.jdt.internal.launching.LibraryInfo;
import org.eclipse.jdt.internal.launching.MacInstalledJREs;
import org.eclipse.jdt.internal.launching.StandardVMType;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.VMStandin;
import org.eclipse.osgi.util.NLS;

/**
 * This class provides the implementation of the {@link IVMInstallType} for Mac OSX.
 *
 * The default VM locations are outlined below. each VM except for developer VMs provide links in the
 * <code>/System/Library/Frameworks/JavaVM.framework/Versions/</code> folder, with a link named
 * <code>CurrentJDK</code> that points to the VM you have set using the Java preference tool in the system preferences.
 * <br><br>
 * The directory structure for Java VMs prior to Snow Leopard is as follows:
 * <pre>
 * /System/Library/Frameworks/JavaVM.framework/Versions/
 *   1.3.1/
 *     Classes/
 *       classes.jar
 *       ui.jar
 *     Home/
 *       src.jar
 * </pre>
 *
 * The directory structure for developer VMs is:
 * <pre>
 * /Library/Java/JavaVirtualMachines/
 *   1.7.0.jdk/
 *     Contents/
 *       Home/
 *         bin/
 *         lib/
 *         ...
 *         src.zip
 * </pre>
 *
 * The directory structure for Snow Leopard and Lion VMs is:
 * <pre>
 * /System/Library/Java/JavaVirtualMachines/
 *   1.6.0.jdk/
 *     Contents/
 *     	 Classes/
 *       Home/
 *         src.zip
 * </pre>
 *
 * @see http://developer.apple.com/library/mac/#qa/qa1170/_index.html
 * @see http://developer.apple.com/library/mac/#releasenotes/Java/JavaSnowLeopardUpdate3LeopardUpdate8RN/NewandNoteworthy/NewandNoteworthy.html#//apple_ref/doc/uid/TP40010380-CH4-SW1
 */
public class MacOSXVMInstallType extends StandardVMType {

	/** The OS keeps all the JVM versions in this directory */
	private static final String JVM_VERSION_LOC= "/System/Library/Frameworks/JavaVM.framework/Versions/";	//$NON-NLS-1$
	private static final File JVM_VERSIONS_FOLDER= new File(JVM_VERSION_LOC);
	/** The name of a Unix link to MacOS X's default VM */
	private static final String CURRENT_JDK= "CurrentJDK";	//$NON-NLS-1$
	/** The root of a JVM */
	private static final String JVM_HOME= "Home";	//$NON-NLS-1$
	/** The doc (for all JVMs) lives here (if the developer kit has been expanded)*/
	private static final String JAVADOC_LOC= "/Developer/Documentation/Java/Reference/";	//$NON-NLS-1$
	/** The doc for 1.4.1 is kept in a sub directory of the above. */
	private static final String JAVADOC_SUBDIR= "/doc/api";	//$NON-NLS-1$
	/**
	 * The name of the src.zip file for the JDK source
	 * @since 3.2.200
	 */
	static final String SRC_ZIP = "src.zip"; //$NON-NLS-1$
	/**
	 * The name of the src.jar file for legacy JDK/JREs
	 * @since 3.2.200
	 */
	static final String SRC_JAR = "src.jar"; //$NON-NLS-1$
	/**
	 * The name of the source used for libraries on the Mac
	 * @since 3.2.200
	 */
	static final String SRC_NAME = "src"; //$NON-NLS-1$
	/**
	 * The name of the Contents folder found within a JRE/JDK folder
	 * @since 3.2.200
	 */
	static final String JVM_CONTENTS = "Contents"; //$NON-NLS-1$
	/**
	 * The name of the Classes folder used to hold the libraries for a legacy JDK/JRE
	 * @since 3.2.200
	 */
	static final String JVM_CLASSES = "Classes"; //$NON-NLS-1$
	/**
	 * The name of the Versions folder for legacy JRE/JDK installs
	 * @since 3.2.200
	 */
	static final String JVM_VERSIONS = "Versions"; //$NON-NLS-1$

	@Override
	public String getName() {
		return Messages.MacOSXVMInstallType_0;
	}

	@Override
	public IVMInstall doCreateVMInstall(String id) {
		return new MacOSXVMInstall(this, id);
	}

	/*
	 * @see IVMInstallType#detectInstallLocation()
	 */
	@Override
	public File detectInstallLocation() {
		try {
			// try to find the VM used to launch Eclipse
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=407402
			File defaultLocation = getJavaHomeLocation();

			// find all installed VMs
			VMStandin[] vms = MacInstalledJREs.getInstalledJREs(null);
			File firstLocation = null;
			IVMInstall firstInstall = null;
			IVMInstall defaultInstall = null;
			for (int i= 0; i < vms.length; i++) {
				File location = vms[i].getInstallLocation();
				IVMInstall install = findVMInstall(vms[i].getId());
				if (install == null) {
					install= vms[i].convertToRealVM();
				}
				if (i == 0) {
					firstLocation = location;
					firstInstall = install;
				}
				if (defaultInstall == null && defaultLocation != null && defaultLocation.equals(location)) {
					defaultInstall = install;
				}
			}

			// determine the default VM
			if (defaultInstall == null) {
				if (defaultLocation != null) {
					// prefer the VM used to launch Eclipse
					String version = System.getProperty("java.version"); //$NON-NLS-1$
					VMStandin standin = new MacInstalledJREs.MacVMStandin(this,
							defaultLocation,
							version == null ? Messages.MacOSXVMInstallType_jre : NLS.bind(Messages.MacOSXVMInstallType_jre_version, version),
							(version == null ? "???" : version),  //$NON-NLS-1$
							String.valueOf(System.currentTimeMillis()));
					defaultInstall = standin.convertToRealVM();
				} else {
					defaultInstall = firstInstall;
					defaultLocation = firstLocation;
				}
			}
			if (defaultInstall != null) {
				try {
					JavaRuntime.setDefaultVMInstall(defaultInstall, null);
				} catch (CoreException e) {
					LaunchingPlugin.log(e);
				}
			}
			return defaultLocation;
		} catch (CoreException e) {
			MacOSXLaunchingPlugin.getDefault().getLog().log(e.getStatus());
			return detectInstallLocationOld();
		}
	}

	/**
	 * The proper way to find installed JREs is to parse the XML output produced from "java_home -X"
	 * (see bug 325777). However, if that fails, revert to the hard coded search.
	 *
	 * @return file that points to the default JRE install
	 */
	private File detectInstallLocationOld() {
		String javaVMName= System.getProperty("java.vm.name");	//$NON-NLS-1$
		if (javaVMName == null) {
			return null;
		}
		if (!JVM_VERSIONS_FOLDER.exists() || !JVM_VERSIONS_FOLDER.isDirectory()) {
			String message= NLS.bind(Messages.MacOSXVMInstallType_1, JVM_VERSIONS_FOLDER);
			LaunchingPlugin.log(message);
			return null;
		}
		// find all installed VMs
		File defaultLocation= null;
		File[] versions= getAllVersionsOld();
		File currentJDK= getCurrentJDKOld();
		for (int i= 0; i < versions.length; i++) {
			File versionFile= versions[i];
			String version= versionFile.getName();
			File home= new File(versionFile, JVM_HOME);
			if (home.exists()) {
				boolean isDefault= currentJDK.equals(versionFile);
				IVMInstall install= findVMInstall(version);
				if (install == null) {
					VMStandin vm= new VMStandin(this, version);
					vm.setInstallLocation(home);
					vm.setName(version);
					vm.setLibraryLocations(getDefaultLibraryLocations(home));
					vm.setJavadocLocation(getDefaultJavadocLocation(home));
					install= vm.convertToRealVM();
				}
				if (isDefault) {
					defaultLocation= home;
					try {
						JavaRuntime.setDefaultVMInstall(install, null);
					} catch (CoreException e) {
						LaunchingPlugin.log(e);
					}
				}
			}
		}
		return defaultLocation;
	}

	/**
	 * The proper way to find installed JREs is to parse the XML output produced from "java_home -X"
	 * (see bug 325777). However, if that fails, revert to the hard coded search.
	 *
	 * @return array of files that point to JRE install directories
	 */
	private File[] getAllVersionsOld() {
		File[] versionFiles= JVM_VERSIONS_FOLDER.listFiles();
		for (int i= 0; i < versionFiles.length; i++) {
			versionFiles[i]= resolveSymbolicLinks(versionFiles[i]);
		}
		return versionFiles;
	}

	/**
	 * The proper way to find the default JRE is to parse the XML output produced from "java_home -X"
	 * and take the first entry in the list. However, if that fails, revert to the hard coded search.
	 *
	 * @return a file that points to the default JRE install directory
	 */
	private File getCurrentJDKOld() {
		return resolveSymbolicLinks(new File(JVM_VERSIONS_FOLDER, CURRENT_JDK));
	}

	private File resolveSymbolicLinks(File file) {
		try {
			return file.getCanonicalFile();
		} catch (IOException ex) {
			return file;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.launching.StandardVMType#getDefaultLibraryInfo(java.io.File)
	 */
	@Override
	protected LibraryInfo getDefaultLibraryInfo(File installLocation) {
		IPath rtjar = getDefaultSystemLibrary(installLocation);
		if(rtjar.toFile().isFile()) {
			//not a Mac OS VM, default to the standard VM type info collection
			return super.getDefaultLibraryInfo(installLocation);
		}
		File classes = new File(installLocation, "../Classes"); //$NON-NLS-1$
		File lib1= new File(classes, "classes.jar"); //$NON-NLS-1$
		File lib2= new File(classes, "ui.jar"); //$NON-NLS-1$

		String[] libs = new String[] { lib1.toString(),lib2.toString() };

		File lib = new File(installLocation, "lib"); //$NON-NLS-1$
		File extDir = new File(lib, "ext"); //$NON-NLS-1$
		String[] dirs = null;
		if (extDir.exists()) {
			dirs = new String[] {extDir.getAbsolutePath()};
		} else {
			dirs = new String[0];
		}

		File endDir = new File(lib, "endorsed"); //$NON-NLS-1$
		String[] endDirs = null;
		if (endDir.exists()) {
			endDirs = new String[] {endDir.getAbsolutePath()};
		} else {
			endDirs = new String[0];
		}

		return new LibraryInfo("???", libs, dirs, endDirs);		 //$NON-NLS-1$
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.launching.StandardVMType#getDefaultSystemLibrarySource(java.io.File)
	 */
	@Override
	protected IPath getDefaultSystemLibrarySource(File libLocation) {
		File parent = libLocation.getParentFile();
		File src = null;
		//Walk the parent hierarchy, stop if we run out of parents or we hit the /Contents directory.
		//For the new shape of JRE/JDKs we can stop once we hit the root Contents folder, for legacy versions
		//we can stop when we hit the Versions folder
		String pname = parent.getName();
		while (parent != null && !JVM_CONTENTS.equals(pname) && !JVM_VERSIONS.equals(pname)) {
			//In Mac OSX supplied JDK/JREs the /Home directory is co-located to the /Classes directory
			if(JVM_CLASSES.equals(pname)) {
				src = new File(parent.getParent(), JVM_HOME);
				src = getSourceInParent(src);
			}
			else {
				src = getSourceInParent(parent);
			}
			if(src != null) {
				if (src.getName().endsWith(".jar")) { //$NON-NLS-1$
					setDefaultRootPath(SRC_NAME);
				} else {
					setDefaultRootPath(""); //$NON-NLS-1$
				}

				return new Path(src.getPath());
			}
			parent = parent.getParentFile();
		}
		setDefaultRootPath(""); //$NON-NLS-1$
		return Path.EMPTY;
	}

	/**
	 * Checks to see if <code>src.zip</code> or <code>src.jar</code> exists in the given parent
	 * folder. Returns <code>null</code> if it does not exist.
	 * <br><br>
	 * The newer naming of the archive is <code>src.zip</code> and the older (pre-1.6) is
	 * <code>src.jar</code>
	 *
	 * @param parent the parent directory
	 * @return the {@link File} for the source archive or <code>null</code>
	 * @since 3.2.200
	 */
	File getSourceInParent(File parent) {
		if(parent.isDirectory()) {
			File src = new File(parent, SRC_ZIP);
			if(src.isFile()) {
				return src;
			}
			src = new File(src, SRC_JAR);
			if(src.isFile()) {
				return src;
			}
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.launching.StandardVMType#validateInstallLocation(java.io.File)
	 */
	@Override
	public IStatus validateInstallLocation(File javaHome) {
		String id= MacOSXLaunchingPlugin.getUniqueIdentifier();
		File java= new File(javaHome, "bin"+File.separator+"java"); //$NON-NLS-2$ //$NON-NLS-1$
		if (java.isFile())
		 {
			return new Status(IStatus.OK, id, 0, "ok", null); //$NON-NLS-1$
		}
		return new Status(IStatus.ERROR, id, 0, Messages.MacOSXVMInstallType_2, null);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.launching.StandardVMType#getDefaultJavadocLocation(java.io.File)
	 */
	@Override
	public URL getDefaultJavadocLocation(File installLocation) {
		// try in local filesystem
		String id= null;
		try {
			String post= File.separator + JVM_HOME;
			String path= installLocation.getCanonicalPath();
			if (path.startsWith(JVM_VERSION_LOC) && path.endsWith(post)) {
				id= path.substring(JVM_VERSION_LOC.length(), path.length()-post.length());
			}
		} catch (IOException ex) {
			// we use the fall back from below
		}
		if (id != null) {
			String s= JAVADOC_LOC + id + JAVADOC_SUBDIR;
			File docLocation= new File(s);
			if (!docLocation.exists()) {
				s= JAVADOC_LOC + id;
				docLocation= new File(s);
				if (!docLocation.exists()) {
					s= null;
				}
			}
			if (s != null) {
				try {
					return new URL("file", "", s);	//$NON-NLS-1$ //$NON-NLS-2$
				} catch (MalformedURLException ex) {
					// we use the fall back from below
				}
			}
		}

		// fall back
		return super.getDefaultJavadocLocation(installLocation);
	}

	/*
	 * Overridden to make it visible.
	 */
	@Override
	protected String getVMVersion(File javaHome, File javaExecutable) {
		return super.getVMVersion(javaHome, javaExecutable);
	}
}
