/*******************************************************************************
 * 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.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.eclipse.cdt.debug.edc.internal.HostOS;
import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl.ExecutionDMC;
import org.eclipse.cdt.debug.edc.internal.snapshot.Album;
import org.eclipse.cdt.debug.edc.internal.snapshot.ISnapshotAlbumEventListener;
import org.eclipse.cdt.debug.edc.internal.snapshot.Snapshot;
import org.eclipse.cdt.debug.edc.internal.snapshot.SnapshotUtils;
import org.eclipse.cdt.debug.edc.launch.EDCLaunch;
import org.eclipse.cdt.debug.edc.services.IEDCExecutionDMC;
import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC;
import org.eclipse.cdt.debug.edc.tests.EDCTestPlugin;
import org.eclipse.cdt.debug.edc.tests.TestUtils;
import org.eclipse.cdt.debug.edc.tests.TestUtils.Condition;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.CoreException;
import org.junit.Assert;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class SnapshotTests extends BaseLaunchTest {

	private boolean testComplete;

	@Test
	public void testSnapshot() throws Exception {
		if (!HostOS.IS_WIN32)
			return;
		testComplete = false;
		TestUtils.showDebugPerspective();
		EDCLaunch launch = createLaunch();
		assertNotNull(launch);
		final DsfSession session = waitForSession(launch);
		assertNotNull(session);
		IEDCExecutionDMC executionDMC = waitForExecutionDMC(session);
		assertNotNull(executionDMC);
		ExecutionDMC threadDMC = TestUtils.waitForSuspendedThread(session);
		Assert.assertNotNull(threadDMC);
		
		Album.addSnapshotAlbumEventListener(new ISnapshotAlbumEventListener() {
			
			public void snapshotSessionEnded(Album album, DsfSession session) {}
			
			public void snapshotOpened(Snapshot snapshot) {}
			
			public void snapshotCreated(Album album, Snapshot snapshot,
					final DsfSession session, StackFrameDMC stackFrame) {
				assertTrue(album.isRecording());
				assertEquals(1, album.getSnapshots().size());
				try {
					assertAlbumStructureCorrect(album);
				} catch (Exception e) {
					EDCTestPlugin.logError(null, e);
				}
				final Snapshot snap = album.getSnapshots().get(0);
				assertNotNull(snap);
				
				session.getExecutor().execute(new DsfRunnable() {
					
					public void run() {
						snap.open(session); // parse snapshot data in album (.dsa)
						try {
							assertSnapshotStructureCorrect(snap);
						} catch (Exception e) {
							EDCTestPlugin.logError(null, e);
							}
						testComplete = true;
					}
				});
			}
		});

		Album.captureSnapshotForSession(session);
		
		TestUtils.wait(new Condition() {
			
			public boolean isConditionValid() {
				return testComplete;
			}
		});
		
		TestUtils.terminateLaunch(launch);
		
	}

	private void assertAlbumStructureCorrect(Album album) throws Exception {
		Document document = (Document) album.getAdapter(Document.class);
		
		assertNotNull(document);
		// find the snapshot meta data element
		NodeList nodeList = document.getElementsByTagName(Album.METADATA);
		assertEquals(1, nodeList.getLength());
		
		assertTrue(album.getLocation().toOSString().endsWith(".dsa"));
		assertEquals(0, album.getCurrentSnapshotIndex());
		
	}
	
	private void assertSnapshotStructureCorrect(Snapshot snapshot) throws Exception {
		
		assertTrue(snapshot.getCreationDate().length() > 0);
		assertTrue(snapshot.getSnapshotFileName().endsWith(".xml"));
		
		Document snapShotdocument = (Document) snapshot.getAdapter(Document.class);
		assertNotNull(snapShotdocument);
		
		// find the snapshot element
		NodeList nodeList = snapShotdocument.getElementsByTagName(Snapshot.SNAPSHOT);
		assertEquals(1, nodeList.getLength());
		
		Element snapshotElement = (Element) nodeList.item(0);
		// check nested execution contexts as list
		nodeList = snapshotElement.getElementsByTagName("execution_context");
		assertEquals(2, nodeList.getLength());
		// check properties of top-level execution context
		// (BlackFlagMinGW.exe)
		Element bfElement = (Element) nodeList.item(0);
		assertNotNull(bfElement.getAttribute("ID"));
		NodeList propsList = bfElement.getChildNodes();
		
		assertTrue(propsList.getLength() > 0);
		
		Element propElement = (Element) bfElement.getElementsByTagName(SnapshotUtils.PROPERTIES)
		.item(0);
		
		Properties properties = createPropertiesFromElement(propElement);
		assertEquals("BlackFlagMinGW.exe", properties.get("Name"));
		assertEquals("root", properties.get("ParentID"));
		String mainExeContextID = (String) properties.get("ID");
// TODO: CanResume is being set as a integer and not a boolean
//		assertEquals("true", properties.get("CanResume"));
		assertEquals(true, properties.get("CanSuspend"));
		assertEquals(true, properties.get("CanTerminate"));
		// check properties of second one (shared lib)
		Element slElement = (Element) nodeList.item(1);

		propElement = (Element) bfElement.getElementsByTagName(SnapshotUtils.PROPERTIES)
		.item(1);
		
		properties = createPropertiesFromElement(propElement);
		assertTrue(properties.containsKey("Name"));
		assertTrue(properties.containsKey("OSID"));
		String subExecContextID = (String) properties.get("ID");
		assertEquals(mainExeContextID, properties.get("ParentID"));
// TODO: CanResume is being set as a integer and not a boolean
//		assertEquals("true", properties.get("CanResume"));
		assertEquals(true, properties.get("CanSuspend"));
		assertEquals(true, properties.get("CanTerminate"));
//		assertEquals("Exception", properties.get("Message")); // This is sometimes "Exception" and sometimes "Shared Library"
		assertEquals(true, properties.get("State"));
		
		// check the registers
		nodeList = slElement.getElementsByTagName("execution_context_registers");
		assertEquals(1, nodeList.getLength());
		Element regGroupElement = (Element) slElement.getElementsByTagName("register_group")
		.item(0);
		assertEquals("register_group", regGroupElement.getTagName());
		String regGroupID = regGroupElement.getAttribute("ID");
		assertTrue("Wrong register group ID: " + regGroupID, regGroupID.equals("GPX") || regGroupID.contains("Basic"));
		
		propElement = (Element) regGroupElement.getElementsByTagName(SnapshotUtils.PROPERTIES)
		.item(0);
		
		properties = createPropertiesFromElement(propElement);
		String name = (String)properties.get("Name");
		assertTrue("Wrong register group name: " + name, name.equals("General") || name.contains("Basic"));
		assertEquals(subExecContextID, properties.get("Context_ID"));
		assertX86RegisterValuesOk(regGroupElement, subExecContextID);

		// check the modules
		nodeList = snapshotElement.getElementsByTagName("execution_context_modules");
		assertEquals(1, nodeList.getLength());
		Element moduleE = (Element) nodeList.item(0);
		Element stackFrameElement = (Element) moduleE.getElementsByTagName(SnapshotUtils.PROPERTIES)
		.item(0);
		
		properties = createPropertiesFromElement(stackFrameElement);
		assertTrue(properties.containsKey("File"));
		assertTrue(properties.containsKey("Loaded"));
		assertTrue(properties.containsKey("ImageBaseAddress"));
		assertTrue(properties.containsKey("CodeSize"));
		
	}

	private void assertX86RegisterValuesOk(Element regGroupElement, String execContextID) {
		NodeList registerNodes = regGroupElement.getElementsByTagName("register");
		assertEquals(16, registerNodes.getLength());
		Set<String> registerNames = new HashSet<String>();
		for (int i = 0; i < registerNodes.getLength(); i++) {
			Element register = (Element) registerNodes.item(i);
			String id = register.getAttribute("ID");
			Node propertiesNode = register.getFirstChild();
			assertNotNull(propertiesNode);
			
			Element propElement = (Element) regGroupElement.getElementsByTagName(SnapshotUtils.PROPERTIES)
			.item(i+1);
			
			Properties properties = createPropertiesFromElement(propElement);
			String name = (String)properties.get("Name");
			assertEquals(id, properties.get("ID"));
			assertEquals(execContextID, properties.get("Context_ID"));
			registerNames.add(name);
		}
		String[] registerNameVals = new String[] { "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "GS", "FS",
				"ES", "DS", "EIP", "CS", "EFL", "SS" };
		Set<String> expectedRegisterIds = new HashSet<String>(Arrays.asList(registerNameVals));
		assertEquals(expectedRegisterIds, registerNames);
	}

	private Properties createPropertiesFromElement(Element propertyElement) {
		Properties properties = new Properties();
		HashMap<String, Object> propMap = new HashMap<String, Object>();
		try {
			SnapshotUtils.initializeFromXML(propertyElement, propMap);
		} catch (CoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Iterator<?> it = propMap.entrySet().iterator();
		while (it.hasNext()){
			Map.Entry<?,?> pairs = (Map.Entry<?,?>)it.next();
	        //System.out.println(pairs.getKey() + " = " + pairs.getValue());
	        properties.put(pairs.getKey(), pairs.getValue());
		}

		return properties;
	}

}
