/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ant.core;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.text.MessageFormat;
import java.util.*;

import org.eclipse.ant.internal.core.AntClassLoader;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.core.InternalCoreAntMessages;
import org.eclipse.core.boot.BootLoader;
import org.eclipse.core.boot.IPlatformRunnable;
import org.eclipse.core.runtime.*;

/**
 * Entry point for running Ant builds inside Eclipse.
 */
public class AntRunner implements IPlatformRunnable {

	private static boolean buildRunning= false;
	protected String buildFileLocation = IAntCoreConstants.DEFAULT_BUILD_FILENAME;
	protected List buildListeners;
	protected String[] targets;
	protected Map userProperties;
	protected int messageOutputLevel = 2; // Project.MSG_INFO
	protected String buildLoggerClassName;
	protected String inputHandlerClassName;
	protected String[] arguments;
	protected String[] propertyFiles;
	protected URL[] customClasspath;
	protected String antHome;

	/**
	 * Sets the build file location on the file system.
	 * 
	 * @param buildFileLocation the file system location of the build file
	 */
	public void setBuildFileLocation(String buildFileLocation) {
		if (buildFileLocation == null) {
			this.buildFileLocation = IAntCoreConstants.DEFAULT_BUILD_FILENAME;
		} else {
			this.buildFileLocation = buildFileLocation;
		}
	}

	/**
	 * Set the message output level.
	 * <p>
	 * Valid values are:
	 * <ul>
	 * <li><code>org.apache.tools.ant.Project.ERR</code>, 
	 * <li><code>org.apache.tools.ant.Project.WARN</code>,
	 * <li><code>org.apache.tools.ant.Project.INFO</code>,
	 * <li><code>org.apache.tools.ant.Project.VERBOSE</code> or
	 * <li><code>org.apache.tools.ant.Project.DEBUG</code>
	 * </ul>
	 * 
	 * @param level the message output level
	 */
	public void setMessageOutputLevel(int level) {
		messageOutputLevel = level;
	}

	/**
	 * Sets the arguments to be passed to the build (e.g. -Dos=win32 -Dws=win32
	 * - verbose).
	 * 
	 * @param arguments the arguments to be passed to the build
	 */
	public void setArguments(String arguments) {
		this.arguments = getArray(arguments);
	}

	/**
	 * Helper method to ensure an array is converted into an ArrayList.
	 */
	private String[] getArray(String args) {
		StringBuffer sb = new StringBuffer();
		boolean waitingForQuote = false;
		ArrayList result = new ArrayList();
		for (StringTokenizer tokens = new StringTokenizer(args, ", \"", true); tokens.hasMoreTokens();) { //$NON-NLS-1$
			String token = tokens.nextToken();
			if (waitingForQuote) {
				if (token.equals("\"")) { //$NON-NLS-1$
					result.add(sb.toString());
					sb.setLength(0);
					waitingForQuote = false;
				} else {
					sb.append(token);
				}
			} else {
				if (token.equals("\"")) { //$NON-NLS-1$
					// test if we have something like -Dproperty="value"
					if (result.size() > 0) {
						int index = result.size() - 1;
						String last = (String) result.get(index);
						if (last.charAt(last.length() - 1) == '=') {
							result.remove(index);
							sb.append(last);
						}
					}
					waitingForQuote = true;
				} else {
					if (!(token.equals(",") || token.equals(" "))) //$NON-NLS-1$ //$NON-NLS-2$
						result.add(token);
				}
			}
		}
		return (String[]) result.toArray(new String[result.size()]);
	}

	/**
	 * Sets the arguments to be passed to the build (e.g. -Dos=win32 -Dws=win32 -verbose).
	 * 
	 * @param arguments the arguments to be passed to the build
	 * @since 2.1
	 */
	public void setArguments(String[] arguments) {
		this.arguments = arguments;
	}

	/**
	 * Sets the targets and execution order.
	 * 
	 * @param executionTargets which targets should be run and in which order
	 */
	public void setExecutionTargets(String[] executionTargets) {
		this.targets = executionTargets;
	}

	/**
	 * Adds a build listener. The parameter <code>className</code>
	 * is the class name of a <code>org.apache.tools.ant.BuildListener</code>
	 * implementation. The class will be instantiated at runtime and the
	 * listener will be called on build events
	 * (<code>org.apache.tools.ant.BuildEvent</code>).
	 *
	 * @param className a build listener class name
	 */
	public void addBuildListener(String className) {
		if (className == null) {
			return;
		}
		if (buildListeners == null) {
			buildListeners = new ArrayList(5);
		}
		buildListeners.add(className);
	}

	/**
	 * Sets the build logger. The parameter <code>className</code>
	 * is the class name of a <code>org.apache.tools.ant.BuildLogger</code>
	 * implementation. The class will be instantiated at runtime and the
	 * logger will be called on build events
	 * (<code>org.apache.tools.ant.BuildEvent</code>).  
	 * Only one build logger is permitted for any build.
	 * 
	 *
	 * @param className a build logger class name
	 */
	public void addBuildLogger(String className) {
		buildLoggerClassName = className;
	}

	/**
	 * Adds user-defined properties. Keys and values must be String objects.
	 * 
	 * @param properties a Map of user-defined properties
	 */
	public void addUserProperties(Map properties) {
		userProperties = properties;
	}

	/**
	 * Returns the build file target information.
	 * 
	 * @return an array containing the target information
	 * 
	 * @see TargetInfo
	 * @since 2.1
	 */
	public synchronized TargetInfo[] getAvailableTargets() throws CoreException {
		Class classInternalAntRunner= null;
		Object runner= null;
		ClassLoader originalClassLoader= Thread.currentThread().getContextClassLoader();
		try {
			ClassLoader loader = getClassLoader();
			Thread.currentThread().setContextClassLoader(loader);
			classInternalAntRunner = loader.loadClass("org.eclipse.ant.internal.core.ant.InternalAntRunner"); //$NON-NLS-1$
			runner = classInternalAntRunner.newInstance();
			// set build file
			Method setBuildFileLocation = classInternalAntRunner.getMethod("setBuildFileLocation", new Class[] { String.class }); //$NON-NLS-1$
			setBuildFileLocation.invoke(runner, new Object[] { buildFileLocation });
			
			setProperties(runner, classInternalAntRunner);
			
			if (arguments != null && arguments.length > 0) {
				Method setArguments = classInternalAntRunner.getMethod("setArguments", new Class[] { String[].class }); //$NON-NLS-1$
				setArguments.invoke(runner, new Object[] { arguments });
			}
						
			// get the info for each targets
			Method getTargets = classInternalAntRunner.getMethod("getTargets", null); //$NON-NLS-1$
			Object results = getTargets.invoke(runner, null);
			// get the default target
			Method getDefault= classInternalAntRunner.getMethod("getDefaultTarget", null); //$NON-NLS-1$
			String defaultName= (String)getDefault.invoke(runner, null);
			// collect the info into target objects
			List infos = (List) results;
			
			ProjectInfo project= new ProjectInfo((String)infos.remove(0), (String)infos.remove(0));
			int i= 0;
			Iterator iter= infos.iterator();
			TargetInfo[] targetInfo= new TargetInfo[infos.size()];
			List info;
			while (iter.hasNext()) {
				info= (List)iter.next();
				targetInfo[i++] = new TargetInfo(project, (String)info.get(0), (String)info.get(1), (String[])info.get(2), info.get(0).equals(defaultName));
			}
			return targetInfo;
		} catch (NoClassDefFoundError e) {
			problemLoadingClass(e);
			//not possible to reach this line
			return new TargetInfo[0];
		} catch (ClassNotFoundException e) {
			problemLoadingClass(e);
			//not possible to reach this line
			return new TargetInfo[0];
		} catch (InvocationTargetException e) {
			handleInvocationTargetException(runner, classInternalAntRunner, e);
			//not possible to reach this line
			return new TargetInfo[0];
		} catch (Exception e) {
			String message = (e.getMessage() == null) ? InternalCoreAntMessages.getString("AntRunner.Build_Failed._3") : e.getMessage(); //$NON-NLS-1$
			throw new CoreException(new Status(IStatus.ERROR, AntCorePlugin.PI_ANTCORE, AntCorePlugin.ERROR_RUNNING_BUILD, message, e));
		} finally {
			Thread.currentThread().setContextClassLoader(originalClassLoader);
		}
	}

	/**
	 * Runs the build file. If a progress monitor is specified it will be
	 * available during the script execution as a reference in the Ant Project
	 * (<code>org.apache.tools.ant.Project.getReferences()</code>). A long-
	 * running task could, for example, get the monitor during its execution and
	 * check for cancellation. The key value to retrieve the progress monitor
	 * instance is <code>AntCorePlugin.ECLIPSE_PROGRESS_MONITOR</code>.
	 * 
	 * Only one build can occur at any given time.
	 * 
	 * Sets the current threads context class loader to the AntClassLoader
	 * for the duration of the build.
	 * 
	 * @param monitor a progress monitor, or <code>null</code> if progress
	 *    reporting and cancellation are not desired
	 */
	public void run(IProgressMonitor monitor) throws CoreException {
		if (buildRunning) {
			IStatus status= new Status(IStatus.ERROR, AntCorePlugin.PI_ANTCORE, AntCorePlugin.ERROR_RUNNING_BUILD, MessageFormat.format(InternalCoreAntMessages.getString("AntRunner.Already_in_progess"), new String[]{buildFileLocation}), null); //$NON-NLS-1$
			throw new CoreException(status);
		}
		buildRunning= true;
		Object runner= null;
		Class classInternalAntRunner= null;
		ClassLoader originalClassLoader= Thread.currentThread().getContextClassLoader();
		try {
			ClassLoader loader = getClassLoader();
			Thread.currentThread().setContextClassLoader(loader);
			classInternalAntRunner = loader.loadClass("org.eclipse.ant.internal.core.ant.InternalAntRunner"); //$NON-NLS-1$
			runner = classInternalAntRunner.newInstance();
			// set build file
			Method setBuildFileLocation = classInternalAntRunner.getMethod("setBuildFileLocation", new Class[] { String.class }); //$NON-NLS-1$
			setBuildFileLocation.invoke(runner, new Object[] { buildFileLocation });
			
			//set the custom classpath
			if (customClasspath != null) {
				Method setCustomClasspath = classInternalAntRunner.getMethod("setCustomClasspath", new Class[] { URL[].class }); //$NON-NLS-1$
				setCustomClasspath.invoke(runner, new Object[] { customClasspath });
			}
			
			// add listeners
			if (buildListeners != null) {
				Method addBuildListeners = classInternalAntRunner.getMethod("addBuildListeners", new Class[] { List.class }); //$NON-NLS-1$
				addBuildListeners.invoke(runner, new Object[] { buildListeners });
			}
			
			if (buildLoggerClassName == null) {
				//indicate that the default logger is not to be used
				buildLoggerClassName= ""; //$NON-NLS-1$
			}
			// add build logger
			Method addBuildLogger = classInternalAntRunner.getMethod("addBuildLogger", new Class[] { String.class }); //$NON-NLS-1$
			addBuildLogger.invoke(runner, new Object[] { buildLoggerClassName });
			
			if (inputHandlerClassName != null) {	
				// add the input handler
				Method setInputHandler = classInternalAntRunner.getMethod("setInputHandler", new Class[] { String.class }); //$NON-NLS-1$
				setInputHandler.invoke(runner, new Object[] { inputHandlerClassName });
			}
			
			if (antHome != null) {	
				Method setAntHome = classInternalAntRunner.getMethod("setAntHome", new Class[] { String.class }); //$NON-NLS-1$
				setAntHome.invoke(runner, new Object[] { antHome });
			}
			
			// add progress monitor
			if (monitor != null) {
				Method setProgressMonitor = classInternalAntRunner.getMethod("setProgressMonitor", new Class[] { IProgressMonitor.class }); //$NON-NLS-1$
				setProgressMonitor.invoke(runner, new Object[] { monitor });
			}
			
			setProperties(runner, classInternalAntRunner);
			
			// set message output level
			Method setMessageOutputLevel = classInternalAntRunner.getMethod("setMessageOutputLevel", new Class[] { int.class }); //$NON-NLS-1$
			setMessageOutputLevel.invoke(runner, new Object[] { new Integer(messageOutputLevel)});
			// set execution targets
			if (targets != null) {
				Method setExecutionTargets = classInternalAntRunner.getMethod("setExecutionTargets", new Class[] { String[].class }); //$NON-NLS-1$
				setExecutionTargets.invoke(runner, new Object[] { targets });
			} 
			// set extra arguments
			if (arguments != null && arguments.length > 0) {
				Method setArguments = classInternalAntRunner.getMethod("setArguments", new Class[] { String[].class }); //$NON-NLS-1$
				setArguments.invoke(runner, new Object[] { arguments });
			}
			// run
			Method run = classInternalAntRunner.getMethod("run", null); //$NON-NLS-1$
			run.invoke(runner, null);
		} catch (NoClassDefFoundError e) {
			problemLoadingClass(e);
		} catch (ClassNotFoundException e) {
			problemLoadingClass(e);
		} catch (InvocationTargetException e) {
			handleInvocationTargetException(runner, classInternalAntRunner, e);
		} catch (Exception e) {
			String message = (e.getMessage() == null) ? InternalCoreAntMessages.getString("AntRunner.Build_Failed._3") : e.getMessage(); //$NON-NLS-1$
			IStatus status= new Status(IStatus.ERROR, AntCorePlugin.PI_ANTCORE, AntCorePlugin.ERROR_RUNNING_BUILD, message, e);
			throw new CoreException(status);
		} finally {
			buildRunning= false;
			Thread.currentThread().setContextClassLoader(originalClassLoader);
		}
	}

	private void setProperties(Object runner, Class classInternalAntRunner)
		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
		// add properties
		if (userProperties != null) {
			Method addUserProperties = classInternalAntRunner.getMethod("addUserProperties", new Class[] { Map.class }); //$NON-NLS-1$
			addUserProperties.invoke(runner, new Object[] { userProperties });
		}
		
		// add property files
		if (propertyFiles != null) {
			Method addPropertyFiles = classInternalAntRunner.getMethod("addPropertyFiles", new Class[] { String[].class }); //$NON-NLS-1$
			addPropertyFiles.invoke(runner, new Object[] { propertyFiles });
		}
	}

	/**
	 * Handles exceptions that are loaded by the Ant Class Loader by
	 * asking the Internal Ant Runner class for the correct error message.
	 * 
	 * Handles OperationCanceledExceptions, nested NoClassDefFoundError and
	 * nested ClassNotFoundException
	 */
	protected void handleInvocationTargetException(Object runner, Class classInternalAntRunner, InvocationTargetException e) throws CoreException {
		Throwable realException = e.getTargetException();
		if (realException instanceof OperationCanceledException) {
			return;
		}
		String message= null;
		if (runner != null) {
			try {
				Method getBuildErrorMessage = classInternalAntRunner.getMethod("getBuildExceptionErrorMessage", new Class[] { Throwable.class }); //$NON-NLS-1$
				message= (String)getBuildErrorMessage.invoke(runner, new Object[] { realException });
			} catch (Exception ex) {
				//do nothing as already in error state
			}
		}
		// J9 throws NoClassDefFoundError nested in a InvocationTargetException
		if (message == null && ((realException instanceof NoClassDefFoundError) || (realException instanceof ClassNotFoundException))) {
			problemLoadingClass(realException);
			return;
		}
		boolean internalError= false;
		if (message == null) {
			//error did not result from a BuildException
			internalError= true;
			message = (realException.getMessage() == null) ? InternalCoreAntMessages.getString("AntRunner.Build_Failed._3") : realException.getMessage(); //$NON-NLS-1$
		}
		IStatus status= new Status(IStatus.ERROR, AntCorePlugin.PI_ANTCORE, AntCorePlugin.ERROR_RUNNING_BUILD, message, realException);
		if (internalError) {
			AntCorePlugin.getPlugin().getLog().log(status);
		}
		throw new CoreException(status);
	}

	protected void problemLoadingClass(Throwable e) throws CoreException {
		String missingClassName= e.getMessage();
		String message;
		if (missingClassName != null) {
			missingClassName= missingClassName.replace('/', '.');
			message= InternalCoreAntMessages.getString("AntRunner.Could_not_find_one_or_more_classes._Please_check_the_Ant_classpath._2"); //$NON-NLS-1$
			message= MessageFormat.format(message, new String[]{missingClassName});
		} else {
			message= InternalCoreAntMessages.getString("AntRunner.Could_not_find_one_or_more_classes._Please_check_the_Ant_classpath._1"); //$NON-NLS-1$
		}
		IStatus status= new Status(IStatus.ERROR, AntCorePlugin.PI_ANTCORE, AntCorePlugin.ERROR_RUNNING_BUILD, message, e);
		AntCorePlugin.getPlugin().getLog().log(status);
		throw new CoreException(status);
	}

	/**
	 * Runs the build file.
	 */
	public void run() throws CoreException {
		run(/*IProgressMonitor*/null);
	}

	/**
	 * Invokes the building of a project object and executes a build using either a given
	 * target or the default target. This method is called when running Eclipse headless
	 * and specifying <code>org.eclipse.ant.core.antRunner</code> as the application.
	 * 
	 * Sets the current threads context class loader to the AntClassLoader
	 * for the duration of the build.
	 *
	 * @param argArray the command line arguments
	 * @exception Exception if a problem occurred during the buildfile execution
	 * @return an exit object (<code>EXIT_OK</code>) indicating normal termination if no exception occurs
	 * @see org.eclipse.core.boot.IPlatformRunnable#run(java.lang.Object)
	 */
	public Object run(Object argArray) throws Exception {
		ClassLoader originalClassLoader= Thread.currentThread().getContextClassLoader();
		try {
			//set the preferences for headless mode
			AntCorePlugin.getPlugin().setRunningHeadless();
			
			// Add debug information if necessary - fix for bug 5672.
			// Since the platform parses the -debug command line arg
			// and removes it from the args passed to the applications,
			// we have to check if Eclipse is in debug mode in order to
			// forward the -debug argument to Ant.
			if (BootLoader.inDebugMode()) {
				String[] args = (String[]) argArray;
				String[] newArgs = new String[args.length + 1];
				for (int i = 0; i < args.length; i++) {
					newArgs[i] = args[i];
				}
				newArgs[args.length] = "-debug"; //$NON-NLS-1$
				argArray = newArgs;
			}
			ClassLoader loader = getClassLoader();
			Thread.currentThread().setContextClassLoader(loader);
			Class classInternalAntRunner = loader.loadClass("org.eclipse.ant.internal.core.ant.InternalAntRunner"); //$NON-NLS-1$
			Object runner = classInternalAntRunner.newInstance();
			Method run = classInternalAntRunner.getMethod("run", new Class[] { Object.class }); //$NON-NLS-1$
			run.invoke(runner, new Object[] { argArray });
		} finally {
			Thread.currentThread().setContextClassLoader(originalClassLoader);
		}

		return EXIT_OK;
	}
	
	private ClassLoader getClassLoader() {
		if (customClasspath == null) {
			return AntCorePlugin.getPlugin().getNewClassLoader();
		} else {
			AntCorePreferences preferences = AntCorePlugin.getPlugin().getPreferences();
			List fullClasspath= new ArrayList();
			fullClasspath.addAll(Arrays.asList(customClasspath));
			fullClasspath.addAll(Arrays.asList(preferences.getExtraClasspathURLs()));
			return new AntClassLoader((URL[])fullClasspath.toArray(new URL[fullClasspath.size()]), preferences.getPluginClassLoaders());
		}
	}
	
	/**
	 * Sets the input handler. The parameter <code>className</code>
	 * is the class name of a <code>org.apache.tools.ant.input.InputHandler</code>
	 * implementation. The class will be instantiated at runtime and the
	 * input handler will be used to respond to &lt;input&gt; requests
	 * Only one input handler is permitted for any build.
	 * 
	 * @param className an input handler class name
	 * @since 2.1
	 */
	public void setInputHandler(String className) {
		inputHandlerClassName= className;
	}
	
	/**
	 * Sets the user specified property files.
	 * @param array of property file paths
	 * @since 2.1
	 */
	public void setPropertyFiles(String[] propertyFiles) {
		this.propertyFiles= propertyFiles;
	}

	/**
	 * Sets the custom classpath to use for this build
	 * @param array of URLs that define the custom classpath
	 */
	public void setCustomClasspath(URL[] customClasspath) {
		this.customClasspath = customClasspath;
	}
	
	/**
	 * Sets the Ant home to use for this build
	 * @param String specifying the Ant home to use
	 * @since 2.1
	 */
 	public void setAntHome(String antHome) {
 		this.antHome= antHome;
 	}
	/**
	 * Returns whether an Ant build is already in progress
	 * 
	 * Only one Ant build can occur at any given time.
	 * 
	 * @since 2.1
	 * @return boolean
	 */
	public static boolean isBuildRunning() {
		return buildRunning;
	}
}
