/*******************************************************************************
 * Copyright (c) 2009, 2010, 2012 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 Overbey (Illinois) - Environment management support
 *******************************************************************************/
package org.eclipse.ptp.internal.rdt.sync.cdt.core.remotemake;

import java.io.IOException;
import java.io.OutputStream;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.ptp.ems.core.EnvManagerConfigString;
import org.eclipse.ptp.ems.core.EnvManagerRegistry;
import org.eclipse.ptp.ems.core.IEnvManager;
import org.eclipse.ptp.internal.rdt.sync.cdt.core.Activator;
import org.eclipse.ptp.rdt.sync.core.SyncConfig;
import org.eclipse.ptp.rdt.sync.core.SyncConfigManager;
import org.eclipse.ptp.rdt.sync.core.SyncFlag;
import org.eclipse.ptp.rdt.sync.core.SyncManager;
import org.eclipse.ptp.rdt.sync.core.exceptions.MissingConnectionException;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteFileManager;
import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.IRemoteProcessBuilder;
import org.eclipse.remote.core.RemoteProcessAdapter;
import org.eclipse.remote.core.exception.RemoteConnectionException;

// TODO (Jeff): Remove/replace NON_ESCAPED_ASCII_CHARS, static initializer, and escape(String) after Bug 371691 is fixed
public class SyncCommandLauncher implements ICommandLauncher {
	public static final String EMS_CONFIG_PROPERTY = "ems-configuration"; //$NON-NLS-1$

	/** ASCII characters that do <i>not</i> need to be escaped on a Bash command line */
	private static final Set<Character> NON_ESCAPED_ASCII_CHARS;

	static {
		NON_ESCAPED_ASCII_CHARS = new HashSet<Character>();
		CharacterIterator it = new StringCharacterIterator("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/._-"); //$NON-NLS-1$
		for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
			NON_ESCAPED_ASCII_CHARS.add(c);
		}
	}

	// See RemoteToolsProcessBuilder ctor and #charEscapify(String, Set<String>)
	private static String escape(String inputString) {
		if (inputString == null) {
			return null;
		}

		final StringBuilder newString = new StringBuilder(inputString.length() + 16);
		final CharacterIterator it = new StringCharacterIterator(inputString);
		for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
			if (c == '\'') {
				newString.append("'\\\\\\''"); //$NON-NLS-1$
			} else if (c > 127 || NON_ESCAPED_ASCII_CHARS.contains(c)) { // Do not escape non-ASCII characters (> 127)
				newString.append(c);
			} else {
				newString.append("\\" + c); //$NON-NLS-1$
			}
		}
		return newString.toString();
	}

	private static String getCommandAsString(IPath commandPath, String[] args) {
		final StringBuilder sb = new StringBuilder();
		sb.append(escape(commandPath.toOSString()));
		sb.append(' ');
		for (String arg : args) {
			sb.append(escape(arg));
			sb.append(' ');
		}
		return sb.toString();
	}

	protected IProject fProject;
	protected Process fProcess;
	protected IRemoteProcess fRemoteProcess;
	protected boolean fShowCommand;
	protected String[] fCommandArgs;

	protected String lineSeparator = "\r\n"; //$NON-NLS-1$

	protected String fErrorMessage;

	protected Map<String, String> remoteEnvMap;

	private boolean shouldSyncBeforeRun = true;
	private boolean shouldSyncAfterRun = true;

	/**
	 * The number of milliseconds to pause between polling.
	 */
	protected static final long DELAY = 50L;

	private List<String> constructCommand(IPath commandPath, String[] args, IRemoteConnection connection, IProgressMonitor monitor)
			throws CoreException {
		SubMonitor progress = SubMonitor.convert(monitor, 100);

		SyncConfig config = SyncConfigManager.getActive(getProject());
		final EnvManagerConfigString projectProperties = new EnvManagerConfigString(config.getProperty(EMS_CONFIG_PROPERTY));
		if (projectProperties.isEnvMgmtEnabled()) {
			// Environment management is enabled for the build. Issue custom Modules/SoftEnv commands to configure the environment.
			IEnvManager envManager = EnvManagerRegistry.getEnvManager(progress.newChild(50), connection);
			try {
				// Create and execute a Bash script which will configure the environment and then execute the command
				final List<String> command = new LinkedList<String>();
				command.add("bash"); //$NON-NLS-1$
				command.add("-l"); //$NON-NLS-1$
				final String bashScriptFilename = envManager.createBashScript(progress.newChild(50), true, projectProperties,
						getCommandAsString(commandPath, args));
				command.add(bashScriptFilename);
				return command;
			} catch (final Exception e) {
				// An error occurred creating the Bash script, so attempt to put the whole thing onto the command line
				Activator.log("Error creating bash script for launch; reverting to bash -l -c", e); //$NON-NLS-1$
				final List<String> command = new LinkedList<String>();
				command.add("bash"); //$NON-NLS-1$
				command.add("-l"); //$NON-NLS-1$
				command.add("-c"); //$NON-NLS-1$
				final String bashCommand = envManager.getBashConcatenation(
						"; ", true, projectProperties, getCommandAsString(commandPath, args)); //$NON-NLS-1$
				command.add(bashCommand);
				return command;
			}
		} else {
			// Environment management disabled. Execute the build command in a login shell (so the default environment is
			// configured).
			final List<String> command = new LinkedList<String>();
			command.add("bash"); //$NON-NLS-1$
			command.add("-l"); //$NON-NLS-1$
			command.add("-c"); //$NON-NLS-1$
			command.add(getCommandAsString(commandPath, args));
			return command;
		}
	}

	/**
	 * Constructs a command array that will be passed to the process
	 */
	protected String[] constructCommandArray(String command, String[] commandArgs) {
		String[] args = new String[1 + commandArgs.length];
		args[0] = command;
		System.arraycopy(commandArgs, 0, args, 1, commandArgs.length);
		return args;
	}

	private Properties convertEnvMapToProperties() {
		Properties properties = new Properties();

		for (String key : remoteEnvMap.keySet()) {
			properties.put(key, remoteEnvMap.get(key));
		}

		return properties;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.cdt.core.ICommandLauncher#execute(org.eclipse.core.runtime.IPath, java.lang.String[], java.lang.String[],
	 * org.eclipse.core.runtime.IPath)
	 */
	@Override
	public Process execute(IPath commandPath, String[] args, String[] env, IPath changeToDirectory, final IProgressMonitor monitor)
			throws CoreException {
		SubMonitor progress = SubMonitor.convert(monitor, 100);

		// if there is no project associated to us then we cannot function... throw an exception
		if (getProject() == null) {
			throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
					"RemoteCommandLauncher has not been associated with a project.")); //$NON-NLS-1$
		}

		SyncConfig config = SyncConfigManager.getActive(getProject());
		if (config == null) {
			return null;
		}

		// Set correct directory
		// For managed projects and configurations other than workspace, the directory is incorrect and needs to be fixed.
		String projectLocalRoot = getProject().getLocation().toPortableString();
		String projectActualRoot = config.getLocation(getProject());
		String fixedDirectory = changeToDirectory.toString().replaceFirst(Pattern.quote(projectLocalRoot),
				Matcher.quoteReplacement(projectActualRoot));
		changeToDirectory = new Path(fixedDirectory);
		fCommandArgs = constructCommandArray(commandPath.toPortableString(), args);

		// Get and setup the connection and remote services for this sync configuration.
		IRemoteConnection connection;
		try {
			connection = config.getRemoteConnection();
		} catch (MissingConnectionException e2) {
			throw new CoreException(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
					"Build canceled because connection does not exist")); //$NON-NLS-1$ 
		}
		if (!connection.isOpen()) {
			try {
				connection.open(progress.newChild(20));
			} catch (RemoteConnectionException e1) {
				// rethrow as CoreException
				throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error opening connection.", e1)); //$NON-NLS-1$
			}
		}

		// Set process's command and environment
		List<String> command = constructCommand(commandPath, args, connection, progress.newChild(10));

		IRemoteProcessBuilder processBuilder = connection.getProcessBuilder(command);

		remoteEnvMap = processBuilder.environment();

		for (String envVar : env) {
			String[] splitStr = envVar.split("=", 2); //$NON-NLS-1$
			if (splitStr.length > 1) {
				remoteEnvMap.put(splitStr[0], splitStr[1]);
			} else if (splitStr.length == 1) {
				// Empty environment variable
				remoteEnvMap.put(splitStr[0], ""); //$NON-NLS-1$
			}
		}

		// set the directory in which to run the command
		IRemoteFileManager fileManager = connection.getFileManager();
		if (changeToDirectory != null && fileManager != null) {
			processBuilder.directory(fileManager.getResource(changeToDirectory.toString()));
		}

		syncOnPreBuild(progress.newChild(60));

		IRemoteProcess p = null;
		try {
			p = processBuilder.start();
		} catch (IOException e) {
			// rethrow as CoreException
			throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error launching remote process.", e)); //$NON-NLS-1$ 
		}

		fRemoteProcess = p;
		fProcess = new RemoteProcessAdapter(p);
		return fProcess;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.cdt.core.ICommandLauncher#getCommandArgs()
	 */
	@Override
	public String[] getCommandArgs() {
		return fCommandArgs;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.cdt.core.ICommandLauncher#getCommandLine()
	 */
	@Override
	public String getCommandLine() {
		return getCommandLine(getCommandArgs());
	}

	private String getCommandLine(String[] commandArgs) {

		if (fProject == null) {
			return null;
		}

		StringBuffer buf = new StringBuffer();
		if (fCommandArgs != null) {
			for (String commandArg : commandArgs) {
				buf.append(commandArg);
				buf.append(' ');
			}
			buf.append(lineSeparator);
		}
		return buf.toString();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.cdt.core.ICommandLauncher#getEnvironment()
	 */
	@Override
	public Properties getEnvironment() {
		return convertEnvMapToProperties();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.cdt.core.ICommandLauncher#getErrorMessage()
	 */
	@Override
	public String getErrorMessage() {
		return fErrorMessage;
	}

	@Override
	public IProject getProject() {
		return fProject;
	}

	protected void printCommandLine(OutputStream os) {
		if (os != null) {
			String cmd = getCommandLine(getCommandArgs());
			try {
				os.write(cmd.getBytes());
				os.flush();
			} catch (IOException e) {
				// ignore;
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.cdt.core.ICommandLauncher#setErrorMessage(java.lang.String)
	 */
	@Override
	public void setErrorMessage(String error) {
		fErrorMessage = error;
	}

	@Override
	public void setProject(IProject project) {
		fProject = project;
	}

	/**
	 * Set whether launcher should sync project after executing. The default behavior is to sync.
	 * 
	 * @param shouldSync
	 */
	public void setSyncAfterRun(boolean shouldSync) {
		shouldSyncAfterRun = shouldSync;
	}

	/**
	 * Set whether launcher should sync project before executing. The default behavior is to sync.
	 * 
	 * @param shouldSync
	 */
	public void setSyncBeforeRun(boolean shouldSync) {
		shouldSyncBeforeRun = shouldSync;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.cdt.core.ICommandLauncher#showCommand(boolean)
	 */
	@Override
	public void showCommand(boolean show) {
		fShowCommand = show;

	}

	private void syncOnPostBuild(IProgressMonitor monitor) throws CoreException {
		SyncConfig config = SyncConfigManager.getActive(getProject());
		if (shouldSyncAfterRun && SyncManager.getSyncAuto() && config.isSyncOnPostBuild()) {
			SyncManager.syncBlocking(null, getProject(), SyncFlag.RL_ONLY, monitor, null);
		}
	}

	private void syncOnPreBuild(IProgressMonitor monitor) throws CoreException {
		SyncConfig config = SyncConfigManager.getActive(getProject());
		if (shouldSyncBeforeRun && config.isSyncOnPreBuild()) {
			switch (SyncManager.getSyncMode(getProject())) {
			case ACTIVE:
				SyncManager.syncBlocking(null, getProject(), SyncFlag.LR_ONLY, monitor, null);
				break;

			case ALL:
				SyncManager.syncAllBlocking(null, getProject(), SyncFlag.LR_ONLY, null);
				break;
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.cdt.core.ICommandLauncher#waitAndRead(java.io.OutputStream, java.io.OutputStream)
	 */
	@Override
	public int waitAndRead(OutputStream out, OutputStream err) {
		if (fShowCommand) {
			printCommandLine(out);
		}

		if (fProcess == null) {
			return ILLEGAL_COMMAND;
		}

		RemoteProcessClosure closure = new RemoteProcessClosure(fRemoteProcess, out, err);
		closure.runBlocking(); // a blocking call
		return OK;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.cdt.core.ICommandLauncher#waitAndRead(java.io.OutputStream, java.io.OutputStream,
	 * org.eclipse.core.runtime.IProgressMonitor)
	 */
	@Override
	public int waitAndRead(OutputStream output, OutputStream err, IProgressMonitor monitor) {
		SubMonitor progress = SubMonitor.convert(monitor, 15);

		if (fShowCommand) {
			printCommandLine(output);
		}

		if (fProcess == null) {
			return ILLEGAL_COMMAND;
		}

		RemoteProcessClosure closure = new RemoteProcessClosure(fRemoteProcess, output, err);
		closure.runNonBlocking();
		while (!progress.isCanceled() && closure.isRunning()) {
			try {
				Thread.sleep(DELAY);
				progress.worked(1);
			} catch (InterruptedException ie) {
				// ignore
			}
		}

		// Poorly named function - actually closes streams and resets variables
		closure.isAlive();

		int state = OK;
		// Operation canceled by the user, terminate abnormally.
		if (progress.isCanceled()) {
			closure.terminate();
			state = COMMAND_CANCELED;
			setErrorMessage(CCorePlugin.getResourceString("CommandLauncher.error.commandCanceled")); //$NON-NLS-1$
		}

		try {
			fProcess.waitFor();
		} catch (InterruptedException e) {
			// ignore
		}

		try {
			syncOnPostBuild(progress.newChild(5));
		} catch (CoreException e) {
			Activator.log(e);
		}

		try {
			// Do not allow the cancel of the refresh, since the
			// builder is external
			// to Eclipse, files may have been created/modified
			// and we will be out-of-sync.
			// The caveat is that for huge projects, it may take a while
			getProject().refreshLocal(IResource.DEPTH_INFINITE, progress.newChild(5));
		} catch (CoreException e) {
			// this should never happen because we should never be building from a
			// state where ressource changes are disallowed
		}

		return state;
	}

}
