/*******************************************************************************
 * 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.ui;

import java.util.concurrent.RejectedExecutionException;

import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.AbstractContainerVMNode;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.ILaunchVMConstants;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerCountingRequestMonitor;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.VMDelegatingPropertiesUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.ui.IMemento;

@SuppressWarnings("restriction")
public class ContainerVMNode extends AbstractContainerVMNode implements IElementMementoProvider {
	public ContainerVMNode(AbstractDMVMProvider provider, DsfSession session) {
		super(provider, session);
	}

	@Override
	public String toString() {
		return "ContainerVMNode(" + getSession().getId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
	}

	@Override
	protected void updateElementsInSessionThread(final IChildrenUpdate update) {
		IProcesses processService = getServicesTracker().getService(IProcesses.class);
		if (processService == null) {
			handleFailedUpdate(update);
			return;
		}

		processService.getProcessesBeingDebugged(null,
				new ViewerDataRequestMonitor<IDMContext[]>(getExecutor(), update) {
					@Override
					public void handleCompleted() {
						if (!isSuccess()) {
							handleFailedUpdate(update);
							return;
						}
						if (getData() != null)
							fillUpdateWithVMCs(update, getData());
						update.done();
					}
				});
	}

	@Override
	protected void updatePropertiesInSessionThread(IPropertiesUpdate[] updates) {
		IPropertiesUpdate[] parentUpdates = new IPropertiesUpdate[updates.length];

		for (int i = 0; i < updates.length; i++) {
			final IPropertiesUpdate update = updates[i];

			final ViewerCountingRequestMonitor countringRm = new ViewerCountingRequestMonitor(ImmediateExecutor
					.getInstance(), updates[i]);
			int count = 0;

			// Create a delegating update which will let the super-class fill in
			// the
			// standard container properties.
			parentUpdates[i] = new VMDelegatingPropertiesUpdate(updates[i], countringRm);
			count++;

			IProcesses processService = getServicesTracker().getService(IProcesses.class);
			final IProcessDMContext procDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(),
					IProcessDMContext.class);

			if (processService == null || procDmc == null) {
				update.setStatus(EDCDebugUI.newErrorStatus(IDsfStatusConstants.INVALID_HANDLE,
						"Service or handle invalid", null)); //$NON-NLS-1$
			} else {
				processService.getExecutionData(procDmc, new ViewerDataRequestMonitor<IThreadDMData>(getExecutor(),
						update) {
					@Override
					public void handleCompleted() {
						if (isSuccess()) {
							fillThreadDataProperties(update, getData());
						} else {
							update.setStatus(getStatus());
						}
						countringRm.done();
					}
				});
				count++;
			}

			countringRm.setDoneCount(count);
		}

		super.updatePropertiesInSessionThread(parentUpdates);
	}

	protected void fillThreadDataProperties(IPropertiesUpdate update, IThreadDMData data) {
		update.setProperty(PROP_NAME, data.getName());
		update.setProperty(ILaunchVMConstants.PROP_ID, "Process id: " + data.getId());
	}

	@Override
	public int getDeltaFlags(Object e) {
		if (e instanceof ICommandControlShutdownDMEvent) {
			return IModelDelta.CONTENT;
		}
		return super.getDeltaFlags(e);
	}

	@Override
	public void buildDelta(Object e, final VMDelta parentDelta, final int nodeOffset,
			final RequestMonitor requestMonitor) {
		if (e instanceof ICommandControlShutdownDMEvent) {
			parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
		} else {
			super.buildDelta(e, parentDelta, nodeOffset, requestMonitor);
			return;
		}
		requestMonitor.done();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seeorg.eclipse.debug.internal.ui.viewers.model.provisional.
	 * IElementMementoProvider
	 * #compareElements(org.eclipse.debug.internal.ui.viewers
	 * .model.provisional.IElementCompareRequest[])
	 */
	private final String MEMENTO_NAME = "CONTAINER_MEMENTO_NAME"; //$NON-NLS-1$

	public void compareElements(IElementCompareRequest[] requests) {
		for (final IElementCompareRequest request : requests) {

			Object element = request.getElement();
			final IMemento memento = request.getMemento();
			final String mementoName = memento.getString(MEMENTO_NAME);

			if (mementoName != null) {
				if (element instanceof IDMVMContext) {

					IDMContext dmc = ((IDMVMContext) element).getDMContext();

					if (dmc instanceof IContainerDMContext) {
						final IProcessDMContext procDmc = findDmcInPath(request.getViewerInput(), request
								.getElementPath(), IProcessDMContext.class);

						if (procDmc != null) {
							try {
								getSession().getExecutor().execute(new DsfRunnable() {
									public void run() {
										final IProcesses processService = getServicesTracker().getService(
												IProcesses.class);
										if (processService != null) {
											processService.getExecutionData(procDmc,
													new ViewerDataRequestMonitor<IThreadDMData>(processService
															.getExecutor(), request) {
														@Override
														protected void handleCompleted() {
															if (getStatus().isOK()) {
																memento
																		.putString(
																				MEMENTO_NAME,
																				"Container." + getData().getName() + getData().getId()); //$NON-NLS-1$
															}
															request.done();
														}
													});
										} else {
											request.done();
										}
									}
								});
							} catch (RejectedExecutionException e) {
								request.done();
							}

							continue;
						}
					}
				}
			}
			request.done();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seeorg.eclipse.debug.internal.ui.viewers.model.provisional.
	 * IElementMementoProvider
	 * #encodeElements(org.eclipse.debug.internal.ui.viewers
	 * .model.provisional.IElementMementoRequest[])
	 */
	public void encodeElements(IElementMementoRequest[] requests) {
		for (final IElementMementoRequest request : requests) {

			Object element = request.getElement();
			final IMemento memento = request.getMemento();

			if (element instanceof IDMVMContext) {

				IDMContext dmc = ((IDMVMContext) element).getDMContext();

				if (dmc instanceof IContainerDMContext) {
					final IProcessDMContext procDmc = findDmcInPath(request.getViewerInput(), request.getElementPath(),
							IProcessDMContext.class);

					if (procDmc != null) {
						try {
							getSession().getExecutor().execute(new DsfRunnable() {
								public void run() {
									final IProcesses processService = getServicesTracker().getService(IProcesses.class);
									if (processService != null) {
										processService.getExecutionData(procDmc,
												new ViewerDataRequestMonitor<IThreadDMData>(processService
														.getExecutor(), request) {
													@Override
													protected void handleCompleted() {
														if (getStatus().isOK()) {
															memento
																	.putString(
																			MEMENTO_NAME,
																			"Container." + getData().getName() + getData().getId()); //$NON-NLS-1$
														}
														request.done();
													}
												});
									} else {
										request.done();
									}
								}
							});
						} catch (RejectedExecutionException e) {
							request.done();
						}

						continue;
					}
				}
			}
			request.done();
		}
	}
}
