/*******************************************************************************
* Copyright (c) 2008, 2011 Oracle. 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:
*     Oracle - initial API and implementation
*******************************************************************************/
package org.eclipse.jpt.common.core.internal.gen;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.ILaunchesListener2;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jpt.common.core.JptCommonCorePlugin;
import org.eclipse.jpt.common.core.internal.JptCommonCoreMessages;
import org.eclipse.osgi.service.datalocation.Location;
import org.osgi.framework.Bundle;

public abstract class AbstractJptGenerator
{
	public static final String PLUGINS_DIR = "plugins/";	  //$NON-NLS-1$

	private IVMInstall jre;
	protected ILaunchConfigurationWorkingCopy launchConfig;
	private ILaunch launch;
	
	protected final IJavaProject javaProject;
	protected final String projectLocation;

	private final boolean isDebug = false;

	// ********** constructors **********

	protected AbstractJptGenerator(IJavaProject javaProject) {
		super();
		this.javaProject = javaProject;
		this.projectLocation = javaProject.getProject().getLocation().toString();
		this.initialize();
	}

	// ********** abstract methods **********
	
	protected abstract String getMainType();

	protected abstract String getLaunchConfigName();

	protected String getBootstrapJarPrefix() {
		throw new RuntimeException("Bootstrap JAR not specified.");   //$NON-NLS-1$;
	}
	
	protected abstract void specifyProgramArguments();

	protected abstract List<String> buildClasspath() throws CoreException;

	// ********** behavior **********
	
	protected void initialize() {
		try {
			this.jre = this.getProjectJRE();
			if (this.jre == null) {
				String message = "Could not identify the VM."; //$NON-NLS-1$
				throw new RuntimeException(message);
			}
			this.launchConfig = this.buildLaunchConfiguration();
		} 
		catch (CoreException e) {
			throw new RuntimeException(e);
		}
	}

	protected void generate(IProgressMonitor monitor) {
		SubMonitor sm = SubMonitor.convert(monitor, 10);
		this.preGenerate(sm.newChild(2));
		if (sm.isCanceled()) {
			throw new OperationCanceledException();
		}
		sm.subTask(JptCommonCoreMessages.GENERATION_CREATING_LAUNCH_CONFIG_TASK);
		this.initializeLaunchConfiguration();
		sm.worked(1);
		if (sm.isCanceled()) {
			throw new OperationCanceledException();
		}

		this.addLaunchListener();
		sm.worked(1);

		if (sm.isCanceled()) {
			throw new OperationCanceledException();
		}
		this.launch = this.saveAndLaunchConfig(sm.newChild(6));
	}
	
	private void initializeLaunchConfiguration() {
		this.specifyJRE();
		
		this.specifyProject(); 
		this.specifyMainType();	
		
		this.specifyProgramArguments();
		this.specifyWorkingDir(); 

		this.specifyClasspathProperties();
	}
	
	private void addLaunchListener() {

		this.getLaunchManager().addLaunchListener(this.buildLaunchListener());
	}
	
	protected abstract void preGenerate(IProgressMonitor monitor);
	
	protected void postGenerate() {
		try {
			if( ! this.isDebug) {
				this.removeLaunchConfiguration();
			}
		}
		catch(CoreException e) {
			throw new RuntimeException(e);
		}
	}

	private ILaunchesListener2 buildLaunchListener() {
		return new ILaunchesListener2() {
			
			public void launchesTerminated(ILaunch[] launches) {
				for(int i = 0; i < launches.length; i++) {
					ILaunch launch = launches[i];
					if (launch.equals(AbstractJptGenerator.this.getLaunch())) {

						AbstractJptGenerator.this.postGenerate();
						return;
					}
				}
			}

			public void launchesAdded(ILaunch[] launches) {
				// not interested to this event
			}

			public void launchesChanged(ILaunch[] launches) {
				// not interested to this event
			}

			public void launchesRemoved(ILaunch[] launches) {
				// not interested to this event
			}
		};
	}

	// ********** Setting Launch Configuration **********
	
	protected void specifyJRE() {
		String jreName = this.jre.getName(); 
		String vmId = this.jre.getVMInstallType().getId();
		this.launchConfig.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH, jreName);
		this.launchConfig.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH, vmId);
	}
	
	private void specifyProject() {
		String projectName = this.getProject().getName();
		this.launchConfig.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, projectName);
	}

	protected IProject getProject() {
		return this.javaProject.getProject();
	}
	
	private void specifyMainType() {
		this.launchConfig.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, this.getMainType());
	}

	protected void specifyClasspathProperties()  {
		List<String> classpath;
		try {
			classpath = this.buildClasspath();
		}
		catch (CoreException e) {
			throw new RuntimeException("An error occured generating a memento", e); //$NON-NLS-1$
		}
		this.launchConfig.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, classpath);
		this.launchConfig.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false);
	}

	// ********** ClasspathEntry **********
	
	protected IRuntimeClasspathEntry getSystemLibraryClasspathEntry() throws CoreException {

		IPath systemLibsPath = new Path(JavaRuntime.JRE_CONTAINER);
		return JavaRuntime.newRuntimeContainerClasspathEntry(systemLibsPath, IRuntimeClasspathEntry.STANDARD_CLASSES);
	}
	
	protected IRuntimeClasspathEntry getDefaultProjectClasspathEntry() {

		IRuntimeClasspathEntry projectEntry = JavaRuntime.newDefaultProjectClasspathEntry(this.javaProject);
		projectEntry.setClasspathProperty(IRuntimeClasspathEntry.USER_CLASSES);
		
		return projectEntry;
	}

	protected static IRuntimeClasspathEntry getArchiveClasspathEntry(IPath archivePath) {
		IRuntimeClasspathEntry archiveEntry = JavaRuntime.newArchiveRuntimeClasspathEntry(archivePath);
		archiveEntry.setClasspathProperty(IRuntimeClasspathEntry.USER_CLASSES);
		
		return archiveEntry;
	}
	

	// ********** LaunchConfig **********
	
	private ILaunch saveAndLaunchConfig(IProgressMonitor monitor) {
		SubMonitor sm = SubMonitor.convert(monitor, 10);
		ILaunchConfiguration configuration = null;
		ILaunch result = null;
		try {
			sm.subTask(JptCommonCoreMessages.GENERATION_SAVING_LAUNCH_CONFIG_TASK);
			configuration = this.launchConfig.doSave();
		}
		catch (CoreException saveException) {
			throw new RuntimeException("Could not save LaunchConfig", saveException); //$NON-NLS-1$
		}
		sm.worked(1);
		if (sm.isCanceled()) {
			throw new OperationCanceledException();
		}
		try {
			sm.subTask(JptCommonCoreMessages.GENERATION_LAUNCHING_CONFIG_TASK);
			result = configuration.launch(ILaunchManager.RUN_MODE, sm.newChild(9));
		}
		catch (CoreException launchException) {
			throw new RuntimeException("An error occured during launch", launchException); //$NON-NLS-1$
		}
		return result;
	}

	// ********** Main arguments **********
	
	protected void appendDebugArgument(StringBuffer sb) {
		if (this.isDebug) {
			sb.append(" -debug"); //$NON-NLS-1$
		}
	}

	// ********** Queries **********
	
	protected ILaunch getLaunch() {
		return this.launch;
	}
	
	protected ILaunchManager getLaunchManager() {
		return DebugPlugin.getDefault().getLaunchManager();
	}
	
	private IVMInstall getProjectJRE() throws CoreException {
		return JavaRuntime.getVMInstall(this.javaProject);
	}

	// ********** Utilities **********

	protected IRuntimeClasspathEntry getBootstrapJarClasspathEntry() {
		return getArchiveClasspathEntry(this.buildBootstrapJarPath());
	}

	protected IPath buildBootstrapJarPath() {
		return this.findGenJarStartingWith(this.getBootstrapJarPrefix());
	}
	
	protected IPath findGenJarStartingWith(String genJarName) {
		try {
			File jarInstallDir = this.getBundleParentDir(JptCommonCorePlugin.PLUGIN_ID);

			List<File> result = new ArrayList<File>();
			this.findFileStartingWith(genJarName, jarInstallDir, result);
			if (result.isEmpty()) {
				throw new RuntimeException("Could not find: " + genJarName + "#.#.#v###.jar in: " + jarInstallDir);   //$NON-NLS-1$ //$NON-NLS-2$
			}
			File genJarFile = result.get(0);
			String genJarPath = genJarFile.getCanonicalPath();
			return new Path(genJarPath);
		}
		catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	// ********** private methods **********

	private File getBundleParentDir(String bundleName) throws IOException {
	
		if (Platform.inDevelopmentMode()) {
			Location eclipseHomeLoc = Platform.getInstallLocation();
			String eclipseHome = eclipseHomeLoc.getURL().getPath();
			if ( ! eclipseHome.endsWith(PLUGINS_DIR)) {
				eclipseHome += PLUGINS_DIR;
			}
			return new File(eclipseHome);
		}
		Bundle bundle = Platform.getBundle(bundleName);
		return FileLocator.getBundleFile(bundle).getParentFile();
	}

	private ILaunchConfigurationWorkingCopy buildLaunchConfiguration() throws CoreException {
		this.removeLaunchConfiguration();

		ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);

		return type.newInstance(null, this.getLaunchConfigName());
	}
	
	private void removeLaunchConfiguration() throws CoreException {

		ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
	
		ILaunchConfiguration[] configurations = manager.getLaunchConfigurations(type);
				for (int i = 0; i < configurations.length; i++) {
			ILaunchConfiguration configuration = configurations[i];
			if (configuration.getName().equals(this.getLaunchConfigName())) {
				configuration.delete();
				break;
			}
		}
	}

	private void findFileStartingWith(String fileName, File directory, List<? super File> list) {
		if(directory.listFiles() == null) {
			throw new RuntimeException("Could not find directory: " + directory);   //$NON-NLS-1$
		}
		for (File file : directory.listFiles()) {
			if (file.getName().startsWith(fileName)) {
				list.add(file);
			}
			if (file.isDirectory()) {
				this.findFileStartingWith(fileName, file, list);
			}
		}
	}
	
	private void specifyWorkingDir() {
		File workingDir = new Path(this.projectLocation).toFile();
		this.launchConfig.setAttribute(IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, workingDir.getAbsolutePath());
	}
	
}
