/*******************************************************************************
 * Copyright (c) 2000, 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
 *     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) {
				setDefaultRootPath(SRC_NAME);
				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);
	}
}
