/*******************************************************************************
 * Copyright (c) 2011 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.math.BigInteger;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.edc.IAddressExpressionEvaluator;
import org.eclipse.cdt.debug.edc.disassembler.EDCInstruction;
import org.eclipse.cdt.debug.edc.disassembler.IDisassembler;
import org.eclipse.cdt.debug.edc.internal.EDCDebugger;
import org.eclipse.cdt.debug.edc.internal.arm.ARMDisassembly;
import org.eclipse.cdt.debug.edc.internal.arm.RangeAndMode;
import org.eclipse.cdt.debug.edc.internal.arm.TargetEnvironmentARM;
import org.eclipse.cdt.debug.edc.internal.arm.disassembler.DisassemblerARM;
import org.eclipse.cdt.debug.edc.services.EDCServicesTracker;
import org.eclipse.cdt.debug.edc.services.ITargetEnvironment;
import org.eclipse.cdt.debug.edc.symbols.TypeUtils;
import org.eclipse.cdt.debug.edc.tests.EDCTestPlugin;
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.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IDisassembly;
import org.eclipse.cdt.dsf.debug.service.IInstruction;
import org.eclipse.cdt.dsf.debug.service.IRegisters;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.utils.Addr32;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.IViewPart;

import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * use the available BlackFlagRVCT snapshot used for register frame tests
 * to test the ARMDisassembly code
 */
public class DisassemblyViewARMBlackFlagRVCT {

	final static String DSF_DISASM_VIEW = "org.eclipse.cdt.dsf.debug.ui.disassembly.view";
	final static byte[] sARMBkptInstr = new byte[] { 0x01, 0, (byte) 0x9f, (byte) 0xef };
	final static byte[] sThumbBkptInstr = new byte[] { 0, (byte) 0xdf, (byte) 0xef };

	private static class ARMBlackFlagRVCTSnapshotAlbum extends SimpleDebuggerTest {
		/* (non-Javadoc)
		 * @see org.eclipse.cdt.debug.edc.debugger.tests.SimpleDebuggerTest#getRequiredLaunchConfigurationType()
		 */
		@Override
		protected String getRequiredLaunchConfigurationType() {
			return "com.nokia.cdt.debug.launch.systemTRKLaunch";
		}
		@Override
		public String getAlbumName() {
			return "RegisterFrameTestsBlackFlagRVCT.dsa";
		}

		static ARMBlackFlagRVCTSnapshotAlbum openAlbum() {
			return new ARMBlackFlagRVCTSnapshotAlbum();
		}
	}

	private static ARMBlackFlagRVCTSnapshotAlbum armAlbum;

	private static ARMDisassembly armDisasm;
	private static IDisassembly.IDisassemblyDMContext disassemblyDMC;
	private static IViewPart disasmView;

	@BeforeClass
	public static void establishARMDisassemblySnapshotSession() {
		try {
			TestUtils.showDebugPerspective();
			armAlbum = ARMBlackFlagRVCTSnapshotAlbum.openAlbum();
			armAlbum.launchAndWaitForSuspendedContext();
			if (armAlbum.launch == null) return;
			EDCServicesTracker edcTracker
			  = new EDCServicesTracker(EDCDebugger.getBundleContext(), armAlbum.session.getId());
			Assert.assertNotNull(edcTracker);
			armDisasm = edcTracker.getService(ARMDisassembly.class);
			Assert.assertNotNull(armDisasm);
			disassemblyDMC
			  = DMContexts.getAncestorOfType(armAlbum.threadDMC, IDisassembly.IDisassemblyDMContext.class);
			disasmView = TestUtils.showView(DSF_DISASM_VIEW);
		} catch (Exception e) {
			Assert.fail(e.getLocalizedMessage());
		}
	}

	@AfterClass
	public static void shutdown() throws Exception {
		TestUtils.hideView(disasmView);
		disassemblyDMC = null;
		armDisasm = null;
		armAlbum.shutdown();
		armAlbum = null;
	}

	@Test
	public void testARMDisassembly() throws Exception {
		if (armAlbum == null) return;
		if (armAlbum.launch == null) {
			System.out.println("== testARMDisassemblyGetInstructionsBigInteger() reporting PASSED but will be skipped.");
			return;
		}
		armAlbum.openSnapshotAndWaitForSuspendedContext(0);
		Thread.sleep(2500);	// wait a little to allow the view to populate and do work
	}

	@Test
	public void testARMDisassemblyGetInstructionsBigInteger() throws Exception {
		if (armAlbum == null) return;
		if (armAlbum.launch == null) {
			System.out.println("== testARMDisassemblyGetInstructionsBigInteger() reporting PASSED but will be skipped.");
			return;
		}

		// Use a Query to synchronize the downstream calls
		Query<IInstruction[]> query = new Query<IInstruction[]>() {
			@Override
			protected void execute(final DataRequestMonitor<IInstruction[]> drm) {
				BigInteger start = new BigInteger("78865830", 16), end = new BigInteger("78865864", 16);
				armDisasm.getInstructions(disassemblyDMC, start, end, drm);
			}
		};
		armAlbum.session.getExecutor().execute(query);
	
		IInstruction[] instrs = query.get(1, TimeUnit.SECONDS);
		Assert.assertTrue("Query returned check", query.isDone());
		Assert.assertNotNull("Returned instructions null check", instrs);
		Assert.assertEquals("Returned instructions array check", 22, instrs.length);
		Assert.assertTrue("EDC Instruction check", instrs[0] instanceof EDCInstruction);

		EDCInstruction edcInstr = (EDCInstruction)instrs[0];
		Assert.assertEquals("Full instruction check", "add\tr2,sp,#0x38", edcInstr.getInstruction());
		Assert.assertEquals("Address check", "2022070320", edcInstr.getAdress().toString());
		Assert.assertEquals("Args check", "r2,sp,#0x38", edcInstr.getArgs());
		Assert.assertNull("Function name check (null for this context)", edcInstr.getFunctionName());
		Assert.assertEquals("Offset check", 0, edcInstr.getOffset());
		// TODO need to change when EDCInstruction#opcode is implemented
		Assert.assertNull("Opcode check (always null right now)", edcInstr.getOpcode());
		Assert.assertEquals("Size check", 2, (int)edcInstr.getSize());
		Assert.assertEquals("(length: 2)  78865830:  add	r2,sp,#0x38", edcInstr.toString());
	}

	@Test
	public void testInternalRangeAndMode() {
		RangeAndMode ram = new RangeAndMode(new Addr32("123456"), null, false, false);
		Assert.assertFalse("RangeAndMode.isThumbMode()", ram.isThumbMode());
		Assert.assertFalse("RangeAndMode.hasSymbols()", ram.hasSymbols());
		Assert.assertEquals("RangeAndMode.getStartAddress()", "123456", ram.getStartAddress().toString());
		Assert.assertNull("RangeAndMode.getEndAddress()", ram.getEndAddress());
		Assert.assertEquals("start = 0x0001e240, end = null, no symbols", ram.toString());

		ram.setThumbMode(true);
		Assert.assertTrue("post RangeAndMode.setThumbMode()", ram.isThumbMode());

		ram.setHasSymbols(true);
		Assert.assertTrue("post RangeAndMode.setHasSymbols()", ram.hasSymbols());

		ram.setStartAddress(new Addr32("123462"));
		Assert.assertEquals("post RangeAndMode.setStartAddress()", "123462", ram.getStartAddress().toString());

		ram.setEndAddress(new Addr32("123478"));
		Assert.assertEquals("post RangeAndMode.setEndAddress()", "123478", ram.getEndAddress().toString());

		Assert.assertEquals("start = 0x0001e246, end = 0x0001e256, thumb, symbols", ram.toString());
	}

	@Test
	public void testInternalTargetEnvironmentARMevaluateLR() throws Exception {
		if (armAlbum == null) return;
		if (armAlbum.launch == null) {
			System.out.println("== testInternalTargetEnvironmentARMevaluateLR() reporting PASSED but will be skipped.");
			return;
		}
		armAlbum.openSnapshotAndWaitForSuspendedContext(4);

		final TargetEnvironmentARM env
		  = (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService();
		Assert.assertNotNull(env);
		
		Query<IAddress> query = new Query<IAddress>() {
			@Override
			protected void execute(final DataRequestMonitor<IAddress> drm) {
				IAddressExpressionEvaluator evaluator
				  = env.getAddressExpressionEvaluator();
				DsfServicesTracker servicesTracker
				  = TestUtils.getDsfServicesTracker(armAlbum.session);
				IRegisters regService = servicesTracker.getService(IRegisters.class);
				try {
					drm.setData(evaluator.evaluate(armAlbum.threadDMC, "lr", regService, null));
				} catch (CoreException e) {
					drm.setStatus(new Status(IStatus.ERROR, EDCTestPlugin.PLUGIN_ID,
											 e.getLocalizedMessage()));
				}
				drm.done();
			}
		};
		armAlbum.session.getExecutor().execute(query);
		
		IAddress lrAddr = query.get(1, TimeUnit.SECONDS);
		Assert.assertTrue(query.isDone());
		Assert.assertNotNull(lrAddr);
		Assert.assertEquals("0x7886583d", lrAddr.toHexAddressString());
	}

	@Test
	public void testInternalTargetEnvironmentARMgetBasicTypeSizes() throws Exception {
		if (armAlbum == null) return;
		if (armAlbum.launch == null) {
			System.out.println("== testInternalTargetEnvironmentARMgetBasicTypeSizes() reporting PASSED but will be skipped.");
			return;
		}
		armAlbum.openSnapshotAndWaitForSuspendedContext(4);

		final TargetEnvironmentARM env
		  = (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService();
		Assert.assertNotNull(env);

		Map<Integer, Integer> basicTypeSizes = env.getBasicTypeSizes();
		Assert.assertEquals("Basic Type Size Test (long long)",
							8, (int)basicTypeSizes.get(TypeUtils.BASIC_TYPE_LONG_LONG)); 
	}

	@Test
	public void testInternalTargetEnvironmentARMgetBreapointInstruction() throws Exception {
		if (armAlbum == null) return;
		if (armAlbum.launch == null) {
			System.out.println("== testInternalTargetEnvironmentARMgetBreapointInstruction() reporting PASSED but will be skipped.");
			return;
		}
		armAlbum.openSnapshotAndWaitForSuspendedContext(4);

		final TargetEnvironmentARM env
		  = (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService();
		Assert.assertNotNull(env);

		byte[] bkptInst = env.getBreakpointInstruction(disassemblyDMC, new Addr32(0x788656e4));
		Assert.assertArrayEquals("Breakpoint Instruction Test", sThumbBkptInstr, bkptInst);
	}

	@Test
	public void testInternalTargetEnvironmentARM() {
		if (armAlbum == null) return;
		if (armAlbum.launch == null) {
			System.out.println("== testInternalTargetEnvironmentARM() reporting PASSED but will be skipped.");
			return;
		}
		if (armDisasm == null) return;
		TargetEnvironmentARM env
		  = (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService();
		Assert.assertNotNull(env);

		IDisassembler disassembler = env.getDisassembler();
		Assert.assertTrue("instanceof check", disassembler instanceof DisassemblerARM);


		int longestInstLength = env.getLongestInstructionLength();
		Assert.assertEquals("Longest Instruction Length Test", 4, longestInstLength);

		int memoryCacheMinimumBlockSize = env.getMemoryCacheMinimumBlockSize();
		Assert.assertEquals("Memory Cache Minimum Block Size Test", 64, memoryCacheMinimumBlockSize);

		Assert.assertEquals("OS Test", ITargetEnvironment.OS_UNKNOWN, env.getOS());
		Assert.assertEquals("PC Register ID Test", "PC", env.getPCRegisterID());
		Assert.assertEquals("Pointer Size Test", 4, env.getPointerSize());
		Assert.assertEquals("Enum Size Test", 4, env.getEnumSize());
		Assert.assertFalse("Char Signed Test", env.isCharSigned());
		Assert.assertTrue("Little Endian Test", env.isLittleEndian(disassemblyDMC));

		boolean isThumbMode = env.isThumbMode(disassemblyDMC, new Addr32(0x788656e4), false);
		Assert.assertTrue("Thumb Mode Test", isThumbMode);
	}

	@Test
	public void coverageInternalTargetEnvironmentARMgetProperty() {
		if (armAlbum == null) return;
		if (armAlbum.launch == null) {
			System.out.println("== coverageInternalTargetEnvironmentARMgetProperty() reporting PASSED but will be skipped.");
			return;
		}
		if (armDisasm == null) return;
		TargetEnvironmentARM env
		  = (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService();
		Assert.assertNotNull(env);

		Assert.assertNull("Property Test (no properties yet supported)", env.getProperty("x"));
	}
}
