/*******************************************************************************
 * Copyright (c) 2007 - 2010 QNX Software Systems 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:
 *     Doug Schaefer, Adrian Petrescu - QNX Software Systems - Initial API and implementation
 *     Andy Jin - Hardware debugging UI improvements, bug 229946
 *     Peter Vidler  - Monitor support (progress and cancellation) bug 242699
 *     Bruce Griffith, Sage Electronic Engineering, LLC - bug 305943
 *              - API generalization to become transport-independent (allow
 *                connections via serial ports and pipes).
 *******************************************************************************/

package org.eclipse.cdt.debug.gdbjtag.core;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.CDebugUtils;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.core.cdi.ICDISession;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.GDBJtagDeviceContribution;
import org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.GDBJtagDeviceContributionFactory;
import org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.IGDBJtagDevice;
import org.eclipse.cdt.debug.mi.core.AbstractGDBCDIDebugger;
import org.eclipse.cdt.debug.mi.core.MIException;
import org.eclipse.cdt.debug.mi.core.MIPlugin;
import org.eclipse.cdt.debug.mi.core.MISession;
import org.eclipse.cdt.debug.mi.core.cdi.Session;
import org.eclipse.cdt.debug.mi.core.cdi.model.Target;
import org.eclipse.cdt.debug.mi.core.command.CLICommand;
import org.eclipse.cdt.debug.mi.core.command.MICommand;
import org.eclipse.cdt.debug.mi.core.command.Command;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIGDBSetNewConsole;
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
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.MultiStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;

/**
 * Debugger class for Jtag debugging (using gdb server)
 */
public class GDBJtagDebugger extends AbstractGDBCDIDebugger {

	private String miVersion;
	
	@Override
	public ICDISession createSession(ILaunch launch, File executable,
			IProgressMonitor monitor) throws CoreException {
		return super.createSession(launch, executable, monitor);
	}

	@Override
	public ICDISession createDebuggerSession(ILaunch launch, IBinaryObject exe,
			IProgressMonitor monitor) throws CoreException {
		return super.createDebuggerSession(launch, exe, monitor);
	}
	
	@Override
	protected CommandFactory getCommandFactory(ILaunchConfiguration config)
			throws CoreException {
		miVersion = MIPlugin.getMIVersion(config);
		return new GDBJtagCommandFactory(miVersion);
	}
	
	@Override
	@SuppressWarnings("deprecation")
	protected void doStartSession(ILaunch launch, Session session, IProgressMonitor monitor) throws CoreException {
		SubMonitor submonitor = SubMonitor.convert(monitor, 100);
		
		try {
			submonitor.subTask(Messages.getString("GDBJtagDebugger.0")); //$NON-NLS-1$
			ILaunchConfiguration config = launch.getLaunchConfiguration();
			ICDITarget[] targets = session.getTargets();
			if (targets.length == 0 || !(targets[0] instanceof Target)) {
				Activator.log(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(),
						DebugPlugin.INTERNAL_ERROR, Messages.getString("GDBJtagDebugger.1"), null)); //$NON-NLS-1$
				return;
			}
			MISession miSession = ((Target)targets[0]).getMISession();
			CommandFactory factory = miSession.getCommandFactory();
			if (submonitor.isCanceled()) {
				throw new OperationCanceledException();
			}
			try {
				MIGDBSetNewConsole newConsole = factory.createMIGDBSetNewConsole();
				miSession.postCommand(newConsole);
				MIInfo info = newConsole.getMIInfo();
				if (info == null) {
					throw new MIException(MIPlugin.getResourceString("src.common.No_answer")); //$NON-NLS-1$
				}
			}
			catch( MIException e ) {
				// We ignore this exception, for example
				// on GNU/Linux the new-console is an error.
			}

			submonitor.worked(10);
			if (submonitor.isCanceled()) {
				throw new OperationCanceledException();
			}
			IGDBJtagDevice gdbJtagDevice;
			try {
				gdbJtagDevice = getGDBJtagDevice(config);
			} catch (NullPointerException e) {
				return;
			}

			List<String> commands = new ArrayList<String>();

			if (submonitor.isCanceled()) {
				throw new OperationCanceledException();
			}
			// execute symbol load
			boolean doLoadSymbols = config.getAttribute(IGDBJtagConstants.ATTR_LOAD_SYMBOLS, IGDBJtagConstants.DEFAULT_LOAD_SYMBOLS);
			if (doLoadSymbols) {
				String symbolsFileName = null;
				// New setting in Helios. Default is true. Check for existence
				// in order to support older launch configs
				if (config.hasAttribute(IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_SYMBOLS) &&
						config.getAttribute(IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_SYMBOLS, IGDBJtagConstants.DEFAULT_USE_PROJ_BINARY_FOR_SYMBOLS)) {
					IPath programFile = CDebugUtils.verifyProgramPath(config);
					if (programFile != null) {
						symbolsFileName = programFile.toOSString();
					}
				}
				else {
					symbolsFileName = config.getAttribute(IGDBJtagConstants.ATTR_SYMBOLS_FILE_NAME, IGDBJtagConstants.DEFAULT_SYMBOLS_FILE_NAME);
					if (symbolsFileName.length() > 0) {
						symbolsFileName = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(symbolsFileName);
					}
				}
				if (symbolsFileName == null) {
					// The launch config GUI should prevent this from happening, but just in case					
					throw new CoreException(new Status( IStatus.ERROR,
							Activator.getUniqueIdentifier(),
							-1, Messages.getString("GDBJtagDebugger.err_no_sym_file"), null));
				}

					// Escape windows path separator characters TWICE, once for Java and once for GDB.
				symbolsFileName = symbolsFileName.replace("\\", "\\\\");

					String symbolsOffset = config.getAttribute(IGDBJtagConstants.ATTR_SYMBOLS_OFFSET, IGDBJtagConstants.DEFAULT_SYMBOLS_OFFSET);
				if (symbolsOffset.length() > 0) {
					symbolsOffset = "0x" + symbolsOffset;					
				}
				commands.clear();
				gdbJtagDevice.doLoadSymbol(symbolsFileName, symbolsOffset, commands);
				monitor.beginTask(Messages.getString("GDBJtagDebugger.loading_symbols"), 1); //$NON-NLS-1$				
				executeGDBScript(getGDBScript(commands), miSession, submonitor.newChild(15));
			}

			if (submonitor.isCanceled()) {
				throw new OperationCanceledException();
			}
			
			// hook up to remote target
			boolean useRemote = config.getAttribute(IGDBJtagConstants.ATTR_USE_REMOTE_TARGET, IGDBJtagConstants.DEFAULT_USE_REMOTE_TARGET);
			if (useRemote) {
				submonitor.subTask(Messages.getString("GDBJtagDebugger.2")); //$NON-NLS-1$
				try {
					commands.clear();				
					if (gdbJtagDevice instanceof IGDBJtagConnection) { 
						URI	connection = new URI(config.getAttribute(IGDBJtagConstants.ATTR_CONNECTION, IGDBJtagConstants.DEFAULT_CONNECTION));
						IGDBJtagConnection device = (IGDBJtagConnection)gdbJtagDevice;
						device.doRemote(connection.getSchemeSpecificPart(), commands);
					} else {
						// use deprecated methods tied to TCP/IP
						String ipAddress = config.getAttribute(IGDBJtagConstants.ATTR_IP_ADDRESS, "");  //$NON-NLS-1$
						int portNumber = config.getAttribute(IGDBJtagConstants.ATTR_PORT_NUMBER, 0);
						gdbJtagDevice.doRemote(ipAddress, portNumber, commands);
					}
				} catch (URISyntaxException e) {
					throw new OperationCanceledException();
				}
				executeGDBScript(getGDBScript(commands), miSession, submonitor.newChild(10));
				if (submonitor.isCanceled()) {
					throw new OperationCanceledException();
				}
			}

			// execute init script
			submonitor.subTask(Messages.getString("GDBJtagDebugger.3")); //$NON-NLS-1$
			submonitor.setWorkRemaining(80); // compensate for optional work above

			// Run device-specific code to reset the board
			if (config.getAttribute(IGDBJtagConstants.ATTR_DO_RESET, IGDBJtagConstants.DEFAULT_DO_RESET)) {
				commands.clear();
				gdbJtagDevice.doReset(commands);
				int defaultDelay = gdbJtagDevice.getDefaultDelay();
				gdbJtagDevice.doDelay(config.getAttribute(IGDBJtagConstants.ATTR_DELAY, defaultDelay), commands);
				executeGDBScript(getGDBScript(commands), miSession, submonitor.newChild(15));
			}
			submonitor.setWorkRemaining(65); // compensate for optional work above

			// Run device-specific code to halt the board
			if (config.getAttribute(IGDBJtagConstants.ATTR_DO_HALT, IGDBJtagConstants.DEFAULT_DO_HALT)) {
				commands.clear();
				gdbJtagDevice.doHalt(commands);
				executeGDBScript(getGDBScript(commands), miSession, submonitor.newChild(15));
			}
			submonitor.setWorkRemaining(50); // compensate for optional work above
			// execute any user defined init command
			executeGDBScript(config, IGDBJtagConstants.ATTR_INIT_COMMANDS, miSession,
					submonitor.newChild(15));

			// execute load
			boolean doLoad = config.getAttribute(IGDBJtagConstants.ATTR_LOAD_IMAGE, IGDBJtagConstants.DEFAULT_LOAD_IMAGE);
			if (doLoad) {
				String imageFileName = null;

				// New setting in Helios. Default is true. Check for existence
				// in order to support older launch configs
				if (config.hasAttribute(IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_IMAGE) &&
						config.getAttribute(IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_IMAGE, IGDBJtagConstants.DEFAULT_USE_PROJ_BINARY_FOR_IMAGE)) {
					IPath programFile = CDebugUtils.verifyProgramPath(config);
					if (programFile != null) {
						imageFileName = programFile.toOSString();
					}
				}
				else {
					imageFileName = config.getAttribute(IGDBJtagConstants.ATTR_IMAGE_FILE_NAME, IGDBJtagConstants.DEFAULT_IMAGE_FILE_NAME);
					if (imageFileName.length() > 0) {
						imageFileName = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(imageFileName);
					}
				}
				if (imageFileName == null) {
					// The launch config GUI should prevent this from happening, but just in case
					throw new CoreException(new Status( IStatus.ERROR,
							Activator.getUniqueIdentifier(),
							-1, Messages.getString("GDBJtagDebugger.err_no_img_file"), null));
				}
				imageFileName = imageFileName.replace("\\", "\\\\");

				String imageOffset = config.getAttribute(IGDBJtagConstants.ATTR_IMAGE_OFFSET, IGDBJtagConstants.DEFAULT_IMAGE_OFFSET);
				if (imageOffset.length() > 0) {
					imageOffset = (imageFileName.endsWith(".elf")) ? "" : "0x" + config.getAttribute(IGDBJtagConstants.ATTR_IMAGE_OFFSET, IGDBJtagConstants.DEFAULT_IMAGE_OFFSET);					
				}
	
				commands.clear();
				gdbJtagDevice.doLoadImage(imageFileName, imageOffset, commands);
				monitor.beginTask(Messages.getString("GDBJtagDebugger.loading_image"), 1); //$NON-NLS-1$
				executeGDBScript(getGDBScript(commands), miSession, submonitor.newChild(20));


			}
			submonitor.setWorkRemaining(15); // compensate for optional work above
		} catch (OperationCanceledException e) {
			if (launch != null && launch.canTerminate()) {
				launch.terminate();
			}
		}
	}

	public void doRunSession(ILaunch launch, ICDISession session, IProgressMonitor monitor) throws CoreException {
		SubMonitor submonitor = SubMonitor.convert(monitor, 100);
		
		try {
			ILaunchConfiguration config = launch.getLaunchConfiguration();
			ICDITarget[] targets = session.getTargets();
			if ( targets.length == 0 || !(targets[0] instanceof Target) )
				return;
			MISession miSession = ((Target)targets[0]).getMISession();

			IGDBJtagDevice gdbJtagDevice;
			try {
				gdbJtagDevice = getGDBJtagDevice(config);
			} catch (NullPointerException e) {
				return;
			}

			if (submonitor.isCanceled()) {
				throw new OperationCanceledException();
			}
			submonitor.worked(20);
			List<String> commands = new ArrayList<String>();
			// Set program counter
			boolean setPc = config.getAttribute(IGDBJtagConstants.ATTR_SET_PC_REGISTER, IGDBJtagConstants.DEFAULT_SET_PC_REGISTER);
			if (setPc) {
				String pcRegister = config.getAttribute(IGDBJtagConstants.ATTR_PC_REGISTER, config.getAttribute(IGDBJtagConstants.ATTR_IMAGE_OFFSET, IGDBJtagConstants.DEFAULT_PC_REGISTER)); 
				gdbJtagDevice.doSetPC(pcRegister, commands);
				executeGDBScript(getGDBScript(commands), miSession, submonitor.newChild(20));
			}
			submonitor.setWorkRemaining(60); // compensate for optional work above

			// execute run script
			monitor.beginTask(Messages.getString("GDBJtagDebugger.18"), 1); //$NON-NLS-1$
			boolean setStopAt = config.getAttribute(IGDBJtagConstants.ATTR_SET_STOP_AT, IGDBJtagConstants.DEFAULT_SET_STOP_AT);
			if (setStopAt) {
				String stopAt = config.getAttribute(IGDBJtagConstants.ATTR_STOP_AT, IGDBJtagConstants.DEFAULT_STOP_AT); 
				commands.clear();
				gdbJtagDevice.doStopAt(stopAt, commands);
				executeGDBScript(getGDBScript(commands), miSession, submonitor.newChild(20));
			}
			submonitor.setWorkRemaining(40); // compensate for optional work above

			boolean setResume = config.getAttribute(IGDBJtagConstants.ATTR_SET_RESUME, IGDBJtagConstants.DEFAULT_SET_RESUME);
			if (setResume) {
				commands.clear();
				gdbJtagDevice.doContinue(commands);
				executeGDBScript(getGDBScript(commands), miSession, submonitor.newChild(20));
			}
			submonitor.setWorkRemaining(20); // compensate for optional work above
			// Run any user defined command
			executeGDBScript(config, IGDBJtagConstants.ATTR_RUN_COMMANDS, miSession, 
					submonitor.newChild(20));
		} catch (OperationCanceledException e) {
			if (launch != null && launch.canTerminate()) {
				launch.terminate();
			}
		}
	}
	
	private void executeGDBScript(String script, MISession miSession, 
			IProgressMonitor monitor) throws CoreException {
		// Try to execute any extra command
		if (script == null || script.length() == 0)
			return;
		script = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(script);
		String[] commands = script.split("\\r?\\n");
		SubMonitor submonitor = SubMonitor.convert(monitor, commands.length);
		for (int j = 0; j < commands.length; ++j) {
			try {
				submonitor.subTask(Messages.getString("GDBJtagDebugger.21") + commands[j]); //$NON-NLS-1$
				Command cmd = null;
				if (commands[j].startsWith("-")) {
					cmd = new MICommand(miVersion, commands[j]);
 				} else {
 					cmd = new CLICommand(commands[j]);
 				}
				miSession.postCommand(cmd, MISession.FOREVER);
				submonitor.worked(1);
				if (submonitor.isCanceled()) {
					throw new OperationCanceledException();
				}
				MIInfo info = cmd.getMIInfo();
				if (info == null) {
					throw new MIException("Timeout"); //$NON-NLS-1$
				}
			} catch (MIException e) {
				MultiStatus status = new MultiStatus(
						Activator.PLUGIN_ID,
						ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR,
						Messages.getString("GDBJtagDebugger.22"), e); //$NON-NLS-1$
				status
						.add(new Status(
								IStatus.ERROR,
								Activator.PLUGIN_ID,
								ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR,
								e == null ? "" : e.getLocalizedMessage(), //$NON-NLS-1$
								e));
				CDebugCorePlugin.log(status);
			}
		}
	}
	
	private void executeGDBScript(ILaunchConfiguration configuration, String attribute,
			MISession miSession, IProgressMonitor monitor) throws CoreException {
		executeGDBScript(configuration.getAttribute(attribute, ""), miSession, monitor); //$NON-NLS-1$
	}

	private IGDBJtagDevice getGDBJtagDevice (ILaunchConfiguration config) 
		throws CoreException, NullPointerException {
		IGDBJtagDevice gdbJtagDevice = null;
		String jtagDeviceName = config.getAttribute(IGDBJtagConstants.ATTR_JTAG_DEVICE, IGDBJtagConstants.DEFAULT_JTAG_DEVICE); 
		GDBJtagDeviceContribution[] availableDevices = GDBJtagDeviceContributionFactory.
			getInstance().getGDBJtagDeviceContribution();
		for (int i = 0; i < availableDevices.length; i++) {
			if (jtagDeviceName.equals(availableDevices[i].getDeviceName())) {
				gdbJtagDevice = availableDevices[i].getDevice();
				break;
			}
		}
		return gdbJtagDevice;
	}
	
	private String getGDBScript(List<String> commands) {
		if (commands.isEmpty())
			return null;
		StringBuffer sb = new StringBuffer();
		for (String cmd : commands) {
			sb.append(cmd);
		}
		return sb.toString();
	}
}
