/*******************************************************************************
 * Copyright (c) 2009, 2010 Nokia 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:
 * Nokia - Initial API and implementation
 *******************************************************************************/
package org.eclipse.cdt.debug.edc.internal.services.dsf;

import java.util.Map;

import org.eclipse.cdt.debug.edc.internal.EDCDebugger;
import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl.ExecutionDMC;
import org.eclipse.cdt.debug.edc.services.AbstractEDCService;
import org.eclipse.cdt.debug.edc.services.IDSFServiceUsingTCF;
import org.eclipse.cdt.debug.edc.services.IEDCDMContext;
import org.eclipse.cdt.debug.edc.services.IEDCExecutionDMC;
import org.eclipse.cdt.debug.edc.tcf.extension.ProtocolConstants;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Immutable;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator2;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
import org.eclipse.cdt.dsf.debug.service.IModules;
import org.eclipse.cdt.dsf.debug.service.IModules.IModuleDMContext;
import org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.tm.tcf.protocol.IService;
import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.IProcesses.ProcessContext;

public class Processes extends AbstractEDCService implements IProcesses, IEventListener, IDSFServiceUsingTCF {

	private org.eclipse.tm.tcf.services.IProcesses tcfProcessesService;
	
	/*
	 * The data of a corresponding thread or process.
	 */
	@Immutable
	protected static class ExecutionDMData implements IThreadDMData {
		String name = "unknown";
		String id = "unknown";

		public ExecutionDMData(ExecutionDMC dmc) {
			Object osid = dmc.getProperty(ProtocolConstants.PROP_OS_ID);
			id = osid.toString();
			name = (String) dmc.getProperty(IEDCDMContext.PROP_NAME);
		}

		public String getId() {
			return id;
		}

		public String getName() {
			return name;
		}

		public boolean isDebuggerAttached() {
			return true;
		}
	}

	public Processes(DsfSession session) {
		super(session, new String[] { IProcesses.class.getName(), Processes.class.getName() });
	}

	@Override
	protected void doInitialize(RequestMonitor requestMonitor) {
		super.doInitialize(requestMonitor);
		getSession().addServiceEventListener(this, null);
	}

	public void attachDebuggerToProcess(IProcessDMContext procCtx, DataRequestMonitor<IDMContext> rm) {
		rm.done();
	}

	public void canDetachDebuggerFromProcess(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
		ExecutionDMC edcDMC = (ExecutionDMC) dmc;
		rm.setData(edcDMC.canDetach());
		rm.done();
	}

	public void canTerminate(IThreadDMContext thread, DataRequestMonitor<Boolean> rm) {
		ExecutionDMC executionDmc = (ExecutionDMC) thread;
		rm.setData(executionDmc.canTerminate());
		rm.done();
	}

	public void debugNewProcess(IDMContext dmc, String file, Map<String, Object> attributes,
			DataRequestMonitor<IDMContext> rm) {
		rm.done();
	}

	/**
	 * Detach debugger from all processes in the debug session.
	 * @param rm
	 */
	public void detachDebuggerFromSession(final RequestMonitor rm) {
		RunControl rcService = getServicesTracker().getService(RunControl.class);
		ExecutionDMC[] processes = rcService.getRootDMC().getChildren();
		
		CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm);
		
		crm.setDoneCount(processes.length);
		
		for (ExecutionDMC p : processes)
			detachDebuggerFromProcess(p, crm);
	}
	
	public void detachDebuggerFromProcess(final IDMContext exeDmc, final RequestMonitor rm) {
		/*
		 * 1. Remove all breakpoints for all modules in the process.
		 * 2. Resume the process.
		 * 3. Detach the process from agent and host debugger.
		 */
		
		// Make sure detach from the process, not just a thread.
		final IProcessDMContext dmc = DMContexts.getAncestorOfType(exeDmc, IProcessDMContext.class);

		final BreakpointsMediator2 bmService = getServicesTracker().getService(BreakpointsMediator2.class);
		if (bmService == null) {
			rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.getUniqueIdentifier(), "Failed to get BreakpointsMediator2 service."));
			rm.done();
			return;
		}
		IModules modulesService = getServicesTracker().getService(IModules.class);
		if (modulesService == null) {
			rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.getUniqueIdentifier(), "Failed to get Modules service."));
			rm.done();
			return;
		}

		ISymbolDMContext symCtx = DMContexts.getAncestorOfType(dmc, ISymbolDMContext.class);
		modulesService.getModules(symCtx, new DataRequestMonitor<IModules.IModuleDMContext[]>(getExecutor(), rm) {

			@Override
			protected void handleCompleted() {
				if (! isSuccess())
					super.handleCompleted();
				else {
					IModuleDMContext[] processModules = getData();
					
					CountingRequestMonitor bpRemovedCRM = new CountingRequestMonitor(getExecutor(), rm) {

						@Override
						protected void handleCompleted() {
							if (! isSuccess()) {
								super.handleCompleted();
								return;
							}
							
							// Now resume the process
							((ExecutionDMC)dmc).resume(new RequestMonitor(getExecutor(), rm){

								@Override
								protected void handleCompleted() {
									if (!isSuccess())
										super.handleCompleted();
									else {
										doDetachDebugger((ExecutionDMC)dmc, rm);
									}
								}
							});
						}
					}; 
					
					int bpTargetsDMCCnt = 0;
					for (IModuleDMContext m : processModules) {
						if (m instanceof IBreakpointsTargetDMContext) {
							// In EDC, each Module is a BpTargetsDMC.
							bpTargetsDMCCnt++;
							bmService.stopTrackingBreakpoints((IBreakpointsTargetDMContext)m, bpRemovedCRM);
						}
					}
					assert bpTargetsDMCCnt > 0;
					
					bpRemovedCRM.setDoneCount(bpTargetsDMCCnt);
				}
			}});
	}

	/**
	 * ask debugger to do final detach: forget the process.
	 * 
	 * @param dmc
	 * @param rm
	 */
	protected void doDetachDebugger(final ExecutionDMC dmc, final RequestMonitor rm) {
		// First detach agent so that the program won't die when the agent dies.
		// Then detach host debugger.
		//
		Protocol.invokeLater(new Runnable() {

			public void run() {
				tcfProcessesService.getContext(dmc.getID(), new org.eclipse.tm.tcf.services.IProcesses.DoneGetContext() {
					
					public void doneGetContext(IToken token, Exception error,
							ProcessContext context) {
						if (error != null) {
							rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.getUniqueIdentifier(), "Fail to get TCF context for process: " + dmc.getID(), error));
							rm.done();
						}
						else {
							context.detach(new org.eclipse.tm.tcf.services.IProcesses.DoneCommand() {
								
								public void doneCommand(IToken token, Exception error) {
									if (error != null)
										rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.getUniqueIdentifier(), "Fail to detach process \"" + dmc.getID() + "\" from TCF agent.", error));
									else {
										// everything ok, now detach from host debugger,
										// which will shutdown the debug session if the process
										// is the last one.
										dmc.detach();
									}
									rm.done();
								}
							});
						}
					}
				});
				
			}});
	}

	public void getDebuggingContext(IThreadDMContext dmc, DataRequestMonitor<IDMContext> rm) {
		rm.done();
	}

	public void getExecutionData(IThreadDMContext dmc, DataRequestMonitor<IThreadDMData> rm) {
		if (dmc instanceof IEDCExecutionDMC)
			rm.setData(new ExecutionDMData((ExecutionDMC) dmc));
		rm.done();
	}

	public void getProcessesBeingDebugged(IDMContext dmc, DataRequestMonitor<IDMContext[]> rm) {
		rm.setData(new IDMContext[0]);
		DsfServicesTracker tracker = getServicesTracker();
		if (tracker != null) {
			RunControl runcontrol = tracker.getService(RunControl.class);
			if (runcontrol != null) {
				IDMContext[] processes = runcontrol.getRootDMC().getChildren();
				rm.setData(processes);
			}
		}
		rm.done();
	}

	public void getRunningProcesses(IDMContext dmc, DataRequestMonitor<IProcessDMContext[]> rm) {
		rm.done();
	}

	public void isDebugNewProcessSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
		rm.setData(false);
		rm.done();
	}

	public void isDebuggerAttachSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
		rm.setData(false);
		rm.done();
	}

	public void isRunNewProcessSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
		rm.setData(false);
		rm.done();
	}

	public void runNewProcess(IDMContext dmc, String file, Map<String, Object> attributes,
			DataRequestMonitor<IProcessDMContext> rm) {
		rm.done();
	}

	public void terminate(IThreadDMContext thread, RequestMonitor requestMonitor) {
		ExecutionDMC executionDmc = (ExecutionDMC) thread;
		executionDmc.terminate(requestMonitor);
	}

	public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
		rm.done();
	}

	// Event handler when a thread or a threadGroup exits
	@DsfServiceEventHandler
	public void eventDispatched(IExitedDMEvent e) {
	}

	public void eventReceived(Object output) {
	}

	public void tcfServiceReady(IService service) {
		assert service instanceof org.eclipse.tm.tcf.services.IProcesses;
		tcfProcessesService = (org.eclipse.tm.tcf.services.IProcesses) service;
	}
}
