/*******************************************************************************
 * 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.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.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.After;
import org.junit.Before;
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;

	@Override
	protected boolean getStopAtMain() {
		return true;
	}

	@Before
	public void launchAndWait() throws Exception {
		if (!HostOS.IS_WIN32)
			return;
		basicLaunch();
	}

	@After
	public void shutdown() {
		TestUtils.shutdownDebugSession(launch, session);
		session = null;
	}

	@Test
	public void testSnapshot() throws Exception {
		testComplete = false;		
		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;
			}
		});
	}

	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;
	}

}
