/*******************************************************************************
 * Copyright (c) 2015 Red Hat, Inc. 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * 	Contributors:
 * 		 Red Hat Inc. - initial API and implementation and/or initial documentation
 *******************************************************************************/
package org.eclipse.wst.jsdt.js.cli.internal.util;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.wst.jsdt.js.cli.CLIPlugin;
/**
 * Utilities for calling and processing the output from external executables.
 * 
 * @author Gorkem Ercan
 *
 */
public class ExternalProcessUtility {

	/**
	 * Executes the given commands asynchronously.
	 *
	 * <p>
	 * If the workingDirectory is null, the current directory for process is used.
	 * </p>
	 * @param command the command line can not be null or empty
	 * @param workingDirectory working directory for the executed command can be null
	 * @param outStreamListener  listener for output, can be null
	 * @param errorStreamListene listener for error output, can be null
	 * @param envp environment variables to set in the process can be null
	 * @throws CoreException if execution fails
	 * @throws IllegalArgumentException 
	 *        <ul>
	 *        <li>If command is null or empty</li>
	 *        <li>If specified workingDirectory does not exist or not a directory</li>
	 *        </ul> 
	 */
	public void execAsync (String [] command, File workingDirectory, 
			IStreamListener outStreamListener,
			IStreamListener errorStreamListener, String[] envp) throws CoreException{
		CLIPlugin.logInfo("Async Execute command line: " + Arrays.toString(command)); //$NON-NLS-1$
		IProcess prcs = exec(command, workingDirectory, new NullProgressMonitor(), envp, null);
		setTracing(command, outStreamListener, errorStreamListener, prcs);
	}
	
	/**
	 * Convenience method to specify command line as a string for {@link #execAsync(String[], File, IStreamListener, IStreamListener, String[])}
	 */
	public void execAsync ( String commandLine, File workingDirectory, 
			IStreamListener outStreamListener, 
			IStreamListener errorStreamListener, String[] envp) throws CoreException{
		checkCommandLine(commandLine);
		this.execAsync(DebugPlugin.parseArguments(commandLine),
				workingDirectory, outStreamListener, errorStreamListener, envp);
	}

	/**
	 * Executes the given commands synchronously.
	 *
	 * <p>
	 * If the workingDirectory is null, the current directory for process is used.
	 * </p>
	 * @param command the command line can not be null or empty
	 * @param workingDirectory working directory for the executed command, can be null
	 * @param outStreamListener  listener for output, can be null
	 * @param errorStreamListene listener for error output, can be null
	 * @param envp environment variables to set in the process, can be null
	 * @param launchConfiguration the launch to add as part of this call, can be null
	 * @return the exit code for the process
	 * @throws CoreException if the execution fails
	 */
	public int execSync ( String[] command, File workingDirectory, 
			IStreamListener outStreamListener, 
			IStreamListener errorStreamListener, IProgressMonitor monitor, 
			String[] envp, ILaunchConfiguration launchConfiguration) throws CoreException{
		if(monitor == null){
			monitor = new NullProgressMonitor();
		}
		CLIPlugin.logInfo("Sync Execute command line: " + Arrays.toString(command)); //$NON-NLS-1$
		IProcess prcs = exec(command, workingDirectory, monitor, envp, launchConfiguration);
		if(prcs == null ){
			return 0;
		}
		setTracing(command, outStreamListener, errorStreamListener, prcs);
		
		while (!prcs.isTerminated()) {
			try {
				if (monitor.isCanceled()) {
					prcs.terminate();
					break;
				}
				Thread.sleep(50);
			} catch (InterruptedException e) {
				CLIPlugin.logError(e, "Exception waiting for process to terminate"); //$NON-NLS-1$
			}
		}
		return prcs.getExitValue();
	}
	
	/**
	 * Executes the given command and returns a handle to the 
	 * process. Should only be used if access to {@link IProcess}
	 * instance is desired. 
	 * 
	 * @param command
	 * @param workingDirectory
	 * @param monitor
	 * @param envp
	 * @param launchConfiguration
	 * @return the process
	 * @throws CoreException
	 */
	public IProcess exec(String[] command, File workingDirectory, 
			IProgressMonitor monitor, String[] envp, 
			ILaunchConfiguration launchConfiguration ) throws CoreException{
		
		checkCommands(command);
		checkWorkingDirectory(workingDirectory);
		if(monitor == null ){
			monitor = new NullProgressMonitor();
		}
		if (envp == null && launchConfiguration != null ){
			envp = DebugPlugin.getDefault().getLaunchManager().getEnvironment(launchConfiguration);
		}
		if (monitor.isCanceled()) {
			return null;
		}
		Process process = DebugPlugin.exec(command, workingDirectory, envp);
		Map<String, String> processAttributes = generateProcessAttributes(command, launchConfiguration);
		Launch launch = new Launch(launchConfiguration, "run", null); //$NON-NLS-1$
		IProcess prcs = DebugPlugin.newProcess(launch, process, command[0], processAttributes);
		DebugPlugin.getDefault().getLaunchManager().addLaunch(launch);
	
		return prcs;
	}
	
	/**
	 * Convenience method to specify command line as a String 
	 * for {@link #execSync(String[], File, IStreamListener, IStreamListener, IProgressMonitor, String[], ILaunchConfiguration)} 
	 */
	public int execSync ( String commandLine, File workingDirectory, 
			IStreamListener outStreamListener, 
			IStreamListener errorStreamListener, IProgressMonitor monitor, String[] envp, ILaunchConfiguration launchConfiguration) throws CoreException{
		String[] cmd = DebugPlugin.parseArguments(commandLine);
		return this.execSync(cmd, workingDirectory, outStreamListener, errorStreamListener, monitor, envp, launchConfiguration);
	}	

	private Map<String, String> generateProcessAttributes(String[] command, ILaunchConfiguration launchConfiguration)
			throws CoreException {
		Map<String, String> processAttributes = new HashMap<String, String>();
		processAttributes.put(IProcess.ATTR_PROCESS_TYPE, command[0]);
		processAttributes.put(IProcess.ATTR_CMDLINE, generateCommandLine(command));
		if(launchConfiguration != null ){
			processAttributes.put(IProcess.ATTR_PROCESS_LABEL,
					launchConfiguration.getAttribute(IProcess.ATTR_PROCESS_LABEL, command[0]));
		}
		return processAttributes;
	}

	
	private void checkWorkingDirectory(File workingDirectory) {
		if(workingDirectory != null && !workingDirectory.isDirectory()){
			throw new IllegalArgumentException(workingDirectory.toString()+ " is not a valid directory"); //$NON-NLS-1$
		}
	}

	private void setTracing(String[] command, IStreamListener outStreamListener, IStreamListener errorStreamListener,
			IProcess prcs) {

// TODO: Handle Debug later
//		if(HybridCore.DEBUG){
//			HybridCore.trace("Creating TracingStreamListeners for " + Arrays.toString(command));
//			outStreamListener = new TracingStreamListener(outStreamListener);
//			errorStreamListener = new TracingStreamListener(outStreamListener);
//		}
		
		if( outStreamListener != null ){
			prcs.getStreamsProxy().getOutputStreamMonitor().addListener(outStreamListener);
		}

		if( errorStreamListener != null ){
			prcs.getStreamsProxy().getErrorStreamMonitor().addListener(errorStreamListener);
		}
	}	

	private void checkCommandLine(String commandLine) {
		if(commandLine == null || commandLine.isEmpty()){
			throw new IllegalArgumentException("Missing command line"); //$NON-NLS-1$
		}
	}
	
	private void checkCommands(String[] command) {
		if(command == null || command.length <1 ){
			throw new IllegalArgumentException("Empty commands array"); //$NON-NLS-1$
		}
	}
	
	private String generateCommandLine(final String[] commandLine) {
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < commandLine.length; i++) {
			buf.append(' ');
			char[] characters = commandLine[i].toCharArray();
			StringBuffer command = new StringBuffer();
			boolean containsSpace = false;
			for (int j = 0; j < characters.length; j++) {
				char character = characters[j];
				if (character == '\"') {
					command.append('\\');
				} else if (character == ' ') {
					containsSpace = true;
				}
				command.append(character);
			}
			if (containsSpace) {
				buf.append('\"');
				buf.append(command);
				buf.append('\"');
			} else {
				buf.append(command);
			}
		}
		return buf.toString();
	}
	
}
