/*******************************************************************************
 * 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.debugger.tests;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.edc.internal.EDCDebugger;
import org.eclipse.cdt.debug.edc.internal.services.dsf.Breakpoints;
import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl;
import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl.ExecutionDMC;
import org.eclipse.cdt.debug.edc.services.EDCServicesTracker;
import org.eclipse.cdt.debug.edc.services.Stack;
import org.eclipse.cdt.debug.edc.tests.EDCTestPlugin;
import org.eclipse.cdt.debug.edc.tests.TestReflectionHelper;
import org.eclipse.cdt.debug.edc.tests.TestUtils;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.debug.service.IStack;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.tm.tcf.services.IRunControl;

public class RunControlDMCSubclass extends BaseLaunchTest {

	private static final String bareDMC_id = "testBareDeviceExcecutionDMC"; //$NON-NLS-1$
	private static final String dbg_derived_types_cpp
	  = "C:\\myprog\\BlackFlagWascana\\src\\dbg_derived_types.cpp"; //$NON-NLS-1$
	private static final String unitTestRCExeDMCContextException
	  = "unitTestRunControlExecutionDMCContextException"; //$NON-NLS-1$

	private RunControl runControlService;
	private Breakpoints breakpointsService;
	private IStack stackService;

	@Override
	protected String getExeFileName() {
		// This is the executable built by Cygwin gcc 3.4.4
		// All source files are built from this folder:
		//   "C:\\myprog\\BlackFlagWascana\\src\\"
		// Note we don't need any source file to perform the test.
		//
		// used because the locations of certain line numbers are known,
		// not because there's no hardcoded break
		return "BlackFlagMinGW_NoHardcodedBreak.exe"; //$NON-NLS-1$
	}

	@Override
	protected IStack getStackService() {
		return stackService;
	}

	@Override
	protected boolean getStopAtMain() {
		return true;
	}

	@Before
	public void launch() throws Exception {
		basicLaunch();
		EDCServicesTracker edcTracker
		  = new EDCServicesTracker(EDCDebugger.getBundleContext(), session.getId());
		assertNotNull(edcTracker);
		runControlService = edcTracker.getService(RunControl.class);
		assertNotNull(runControlService);
		stackService = edcTracker.getService(Stack.class);
		assertNotNull(stackService);
		breakpointsService = edcTracker.getService(Breakpoints.class);
		assertNotNull(breakpointsService);
	}

	@After
	public void shutdown() {
		threadDMC.purgeFromDebugger();
		TestUtils.shutdownDebugSession(launch, session);
		session = null;
	}

	@Test
	public void testBareDeviceExecutionDMC() throws Exception {
		Map<String, Object> bdeDMCProps = new HashMap<String, Object>();
		bdeDMCProps.put(RunControl.PROP_IS_CONTAINER, false);
		bdeDMCProps.put(RunControl.BareDeviceExecutionDMC.PROP_ID, bareDMC_id);
		RunControl.BareDeviceExecutionDMC bdeDMC
		  = runControlService.new BareDeviceExecutionDMC(threadDMC, bdeDMCProps, threadDMC.getTCFContext());
		assertNotNull(bdeDMC);
		assertTrue(bdeDMC.canDetach());

		// 		DMCSuspendedEvent createSuspendedEvent(StateChangeReason reason, Map<String, Object> properties)
		Map<String, Object> cseProps = new HashMap<String, Object>();
		cseProps.put("cseKey1", "cseVal1");
		cseProps.put("cseKey2", "cseVal2");
		RunControl.StateChangeReason scr = RunControl.StateChangeReason.CONTAINER;
		Object[] cseArgs = new Object[] {scr, cseProps};
		Class<?>[] cseArgClasses = new Class<?>[] {scr.getClass(), Map.class};
		RunControl.ContainerSuspendedEvent cse
		  = (RunControl.ContainerSuspendedEvent)TestReflectionHelper
				.objectFromPrivateFunctionWithArgs(bdeDMC, "createSuspendedEvent",
						cseArgs, cseArgClasses);
		assertNotNull(cse);

		Map<String, Object> cseParams = cse.getParams();
		assertNotNull(cseParams);
		assertEquals(cseProps, cseParams);

		RunControl.IExecutionDMContext[] dmc = cse.getTriggeringContexts();
		assertNotNull(dmc);
		assertEquals(1, dmc.length);
		assertEquals(bdeDMC, dmc[0]);

		// 		protected DMCResumedEvent createResumedEvent()
		RunControl.ContainerResumedEvent cre
		  = (RunControl.ContainerResumedEvent)TestReflectionHelper
				.objectFromPrivateFunctionWithArgs(bdeDMC, "createResumedEvent", null);
		assertNotNull(cre);

		dmc = cre.getTriggeringContexts();
		assertNotNull(dmc);
		assertEquals(1, dmc.length);
		assertEquals(bdeDMC, dmc[0]);
	}

	@Test
	public void testRootDMC() {
		RunControl.RootExecutionDMC rootDMC = runControlService.getRootDMC();
		assertNotNull(rootDMC);
		assertNull(rootDMC.getSymbolDMContext());
		assertFalse(rootDMC.canDetach());
		assertFalse(rootDMC.canStep());
	}

	@Test
	public void testStepIntoOneInstruction() throws Exception {
		waitRunToLine(runControlService, dbg_derived_types_cpp, 285);

		Query<IStatus> query = new Query<IStatus>() {
			@Override
			protected void execute(final DataRequestMonitor<IStatus> drm) {
				runControlService.step(threadDMC, StepType.INSTRUCTION_STEP_INTO, drm);
			}
		};

		session.getExecutor().execute(query);

		query.get(5, TimeUnit.SECONDS);
		assertTrue(query.isDone());

		updateSuspendedFrame(200);
		assertControlIsAt("dbg_derived_types.cpp", "structs", 40);
	}

	@Test
	public void testStepOut() throws Exception {
		waitRunToLine(runControlService, dbg_derived_types_cpp, 57, 2000);
		TestUtils.waitForUIUpdate(4000);

		// set this so it stops someplace, even if it's after the expected step out point
		setTempBreakpoint(breakpointsService, dbg_derived_types_cpp, 288);

		Query<IStatus> query = new Query<IStatus>() {
			@Override
			protected void execute(final DataRequestMonitor<IStatus> drm) {
				runControlService.step(threadDMC, StepType.STEP_RETURN, drm);
			}
		};

		try {
			session.getExecutor().execute(query);
		} catch (Exception e) {
			fail(e.getLocalizedMessage());
		}

		IStatus status = query.get(5, TimeUnit.SECONDS);
		if (status != null) {
			assertTrue(status.getSeverity() == IStatus.INFO);
			assertEquals(RunControl.STEP_RETURN_NOT_SUPPORTED, status.getMessage());
		} else {
			updateSuspendedFrame(200);
			assertControlIsAt("dbg_derived_types.cpp", "dbg_derived_types", 286);
		}
	}

	@Test
	public void testThreadDMC() {
		assertFalse(threadDMC.canDetach());
		ExecutionDMC exeDMC = null;
		try {
			// first arg is a map of properties, but we expect an immediate assert
			exeDMC = threadDMC.contextAdded(null, threadDMC.getTCFContext());
		} catch (AssertionError ae) {
			// this is expected
		}
		assertNull(exeDMC);
	}

	@Test
	public void unitTestRunControlGetModelData() throws Exception {
		Query<Boolean> query = new Query<Boolean>() {
			@Override
			protected void execute(final DataRequestMonitor<Boolean> drm) {
				runControlService.getModelData(threadDMC, drm);
			}
		};

		session.getExecutor().execute(query);

		query.get(2, TimeUnit.SECONDS);
		assertTrue(query.isDone());
	}

	@Test
	public void unitTestRunControlStepOverOneInstruction() throws Exception {
		waitRunToLine(runControlService, dbg_derived_types_cpp, 285);

		final IAddress line285Addr = waitGetLineAddress(dbg_derived_types_cpp, 285);
		final Class<?>[] stepOverArgClasses = new Class<?>[] {ExecutionDMC.class, IAddress.class, RequestMonitor.class};
		// 	private void stepOverOneInstruction(ExecutionDMC, IAddress pcAddress, RequestMonitor)
		Query<Boolean> query = new Query<Boolean>() {
			@Override
			protected void execute(final DataRequestMonitor<Boolean> drm) {
				Object[] stepOverArgs = new Object[] {threadDMC, line285Addr, drm};
				try {
					TestReflectionHelper.objectFromPrivateFunctionWithArgs(
							runControlService, "stepOverOneInstruction", stepOverArgs, stepOverArgClasses);
				} catch (Exception e) {
					drm.setStatus(new Status(IStatus.ERROR, EDCTestPlugin.PLUGIN_ID,
							"exception thrown invoking RunControl#stepOverOneInstruction()"//$NON-NLS-1$
							+ e.getLocalizedMessage()));
					drm.done();
				}
			}
		};

		session.getExecutor().execute(query);

		query.get(5, TimeUnit.SECONDS);
		assertTrue(query.isDone());

		updateSuspendedFrame(100);
		assertControlIsAt("dbg_derived_types.cpp", "dbg_derived_types", 286);
	}

	@Test 
	public void coverageRunControlGetSteppingStartTime() {
		long steppingStartTime = RunControl.getSteppingStartTime();
		if (RunControl.timeStepping()) {
			
		} else {
			assertEquals(0, steppingStartTime);
		}
	}

	@Test 
	public void coverageRunControlRunListener() throws Exception {
		IRunControl.RunControlListener runListener
		  = (IRunControl.RunControlListener)
		  		TestReflectionHelper.getPrivateField("runListener", runControlService);

		assertNotNull(runListener);

		// the following will also test ExecutionDMC#contextException()
		runListener.contextException(threadDMC.getID(), unitTestRCExeDMCContextException);
		Thread.sleep(400);	// wait a little for the exception to propagate
		String propMessage = (String)threadDMC.getProperty(RunControl.PROP_MESSAGE);
		assertEquals(unitTestRCExeDMCContextException, propMessage);

		// the next 3 are empty and expected to do nothing
		runListener.containerResumed(null);
		runListener.containerSuspended(null, null, null, null, null);
		runListener.contextChanged(null);

		// resume our thread
		assertTrue(threadDMC.isSuspended());
		runListener.contextResumed(threadDMC.getID());
		Thread.sleep(400);	// wait a little for it to get re-started
		assertFalse(threadDMC.isSuspended());
	}

}
