/*******************************************************************************
 * 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.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import junit.framework.Assert;

import org.eclipse.cdt.debug.edc.services.Registers;
import org.eclipse.cdt.debug.edc.services.Registers.RegisterDMC;
import org.eclipse.cdt.debug.edc.tests.TestUtils;
import org.eclipse.cdt.debug.edc.tests.TestUtils.Condition;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.CompositeDMContext;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.IFormattedDataDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IBitFieldDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IBitFieldDMData;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IMnemonic;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMData;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMData;
import org.eclipse.core.runtime.CoreException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class RegisterView {

	static class RegisterViewLaunch extends BaseLaunchTest {
		@Override
		protected boolean getStopAtMain() {
			return true;
		}
	}

	static RegisterViewLaunch testLaunch;
	static Registers regService;
	static IRegisterDMContext[] regDMCs;
	static IRegisterGroupDMContext regGroupDMC;
	
	@BeforeClass
	public static void launch() throws Exception {
		testLaunch = new RegisterViewLaunch();
		testLaunch.basicLaunch();
		regService = TestUtils.getService(testLaunch.session, Registers.class);
		regGroupDMC = waitForRegisterGroup(regService);
		String regGroupString = regGroupDMC.toString();
		Assert.assertTrue("RegisterGroup toString()", regGroupString.startsWith("DMContext [id=")); 
		Assert.assertTrue("RegisterGroup toString()", regGroupString.endsWith("].group[Basic]")); 
		regDMCs = waitForRegisterDMCs(regGroupDMC, regService);
		String regDMCString = regDMCs[0].toString();
		Assert.assertTrue("RegisterDMC[0] toString()", regDMCString.startsWith("DMContext [id="));
		Assert.assertTrue("RegisterDMC[0] toString()", regDMCString.endsWith("].group[Basic].register[EAX]"));
	}

	@AfterClass
	public static void shutdown() {
		TestUtils.shutdownDebugSession(testLaunch.launch, testLaunch.session);
		testLaunch = null;
	}

	@Test
	public void testRegisterView() throws Exception {
		testRegisterWrites(regService, regDMCs);
	}

	@Test
	public void coverageInternalFindBitFieldNotSupported() throws Exception {
		Query<IBitFieldDMContext> query = new Query<IBitFieldDMContext>() {
			@Override
			protected void execute(final DataRequestMonitor<IBitFieldDMContext> drm) {
				regService.findBitField(testLaunch.threadDMC, "", drm);
			}
		};
		testLaunch.session.getExecutor().execute(query);

		try {
			IBitFieldDMContext unexpectedResult = query.get(1, TimeUnit.SECONDS);
			Assert.assertNull("Not expecting filled IBitFieldDMContext", unexpectedResult);
		} catch (ExecutionException e) {
			Assert.assertTrue(e.getCause() instanceof CoreException);
			Assert.assertEquals("findBitField not supported", e.getCause().getMessage());
		}
	}

	@Test
	public void coverageInternalFindRegisterNotSupported() throws Exception {
		Query<IRegisterDMContext> query = new Query<IRegisterDMContext>() {
			@Override
			protected void execute(final DataRequestMonitor<IRegisterDMContext> drm) {
				regService.findRegister(testLaunch.threadDMC, "", drm);
			}
		};
		testLaunch.session.getExecutor().execute(query);

		try {
			IRegisterDMContext unexpectedResult = query.get(1, TimeUnit.SECONDS);
			Assert.assertNull("Not expecting filled IRegisterDMContext", unexpectedResult);
		} catch (ExecutionException e) {
			Assert.assertTrue(e.getCause() instanceof CoreException);
			Assert.assertEquals("findRegister not supported", e.getCause().getMessage());
		}
	}

	@Test
	public void coverageInternalFindRegisterGroupNotSupported() throws Exception {
		Query<IRegisterGroupDMContext> query = new Query<IRegisterGroupDMContext>() {
			@Override
			protected void execute(final DataRequestMonitor<IRegisterGroupDMContext> drm) {
				regService.findRegisterGroup(testLaunch.threadDMC, "", drm);
			}
		};
		testLaunch.session.getExecutor().execute(query);

		try {
			IRegisterGroupDMContext unexpectedResult = query.get(1, TimeUnit.SECONDS);
			Assert.assertNull("Not expecting filled IRegisterGroupDMContext", unexpectedResult);
		} catch (ExecutionException e) {
			Assert.assertTrue(e.getCause() instanceof CoreException);
			Assert.assertEquals("findRegisterGroup not supported", e.getCause().getMessage());
		}
	}

	@Test
	public void testInternalGetAvailableFormats() throws Exception {
		Query<String[]> query = new Query<String[]>() {
			@Override
			protected void execute(final DataRequestMonitor<String[]> drm) {
				regService.getAvailableFormats((IFormattedDataDMContext)null, drm);
			}
		};
		testLaunch.session.getExecutor().execute(query);

		String[] expectedResult = query.get(1, TimeUnit.SECONDS);
		Assert.assertTrue(query.isDone());
		Assert.assertNotNull("Registers.getAvailableFormats() result", expectedResult);
		Assert.assertEquals("Registers.getAvailableFormats() result size", 5, expectedResult.length);

		String[] comparisonFormats
		  = new String[]
		         { IFormattedValues.HEX_FORMAT,
				   IFormattedValues.DECIMAL_FORMAT,
				   IFormattedValues.OCTAL_FORMAT,
				   IFormattedValues.BINARY_FORMAT,
				   IFormattedValues.NATURAL_FORMAT };
		for (int i=0; i<comparisonFormats.length; ++i) {
			Assert.assertEquals("Registers.getAvailableFormats()[" + i + "] contents",
					comparisonFormats[i], expectedResult[i]);
		}
	}

	@Test
	public void coverageInternalGetBitFieldsNotSupported() throws Exception {
		Query<IBitFieldDMContext[]> query = new Query<IBitFieldDMContext[]>() {
			@Override
			protected void execute(final DataRequestMonitor<IBitFieldDMContext[]> drm) {
				regService.getBitFields(testLaunch.threadDMC, drm);
			}
		};
		testLaunch.session.getExecutor().execute(query);

		try {
			IBitFieldDMContext[] unexpectedResult = query.get(1, TimeUnit.SECONDS);
			Assert.assertNull("Not expecting filled IBitFieldDMContext[]", unexpectedResult);
		} catch (ExecutionException e) {
			Assert.assertTrue(e.getCause() instanceof CoreException);
			Assert.assertEquals("BitField not supported", e.getCause().getMessage());
		}
	}

	@Test
	public void coverageInternalGetBitFieldDataNotSupported() throws Exception {
		Query<IBitFieldDMData> query = new Query<IBitFieldDMData>() {
			@Override
			protected void execute(final DataRequestMonitor<IBitFieldDMData> drm) {
				regService.getBitFieldData((IBitFieldDMContext)null, drm);
			}
		};
		testLaunch.session.getExecutor().execute(query);

		try {
			IBitFieldDMData unexpectedResult = query.get(1, TimeUnit.SECONDS);
			Assert.assertNull("Not expecting filled IBitFieldDMData", unexpectedResult);
		} catch (ExecutionException e) {
			Assert.assertTrue(e.getCause() instanceof CoreException);
			Assert.assertEquals("Bit fields not yet supported", e.getCause().getMessage());
		}
	}

	@Test
	public void testInternalGetFormattedExpressionValue() throws Exception {
		final FormattedValueDMContext formattedValueDMC
		  = regService.getFormattedValueContext(regDMCs[0], IFormattedValues.NATURAL_FORMAT);
		Query<FormattedValueDMData> query = new Query<FormattedValueDMData>() {
			@Override
			protected void execute(final DataRequestMonitor<FormattedValueDMData> drm) {
				regService.getModelData(formattedValueDMC, drm);
			}
		};
		testLaunch.session.getExecutor().execute(query);
		FormattedValueDMData formatValueDMData = query.get(1, TimeUnit.SECONDS);
		Assert.assertTrue(query.isDone());
		Assert.assertNotNull(formatValueDMData);
	}

	@Test
	public void testInternalGetRegisterData() throws Exception {
		Query<IRegisterDMData> query = new Query<IRegisterDMData>() {
			@Override
			protected void execute(final DataRequestMonitor<IRegisterDMData> drm) {
				regService.getModelData(regDMCs[0], drm);
			}
		};
		testLaunch.session.getExecutor().execute(query);
		IRegisterDMData regDMData = query.get(1, TimeUnit.SECONDS);
		Assert.assertTrue(query.isDone());
		Assert.assertNotNull(regDMData);
		Assert.assertNull("RegisterData.getDescription()", regDMData.getDescription());
		Assert.assertEquals("RegisterData.getName()", "EAX", regDMData.getName());		
		Assert.assertFalse("RegisterData.hasSideEffects()", regDMData.hasSideEffects());
		Assert.assertFalse("RegisterData.isFloat()", regDMData.isFloat());
		Assert.assertTrue("RegisterData.isReadable()", regDMData.isReadable());
		Assert.assertFalse("RegisterData.isReadOnce()", regDMData.isReadOnce());
		Assert.assertFalse("RegisterData.isVolatile()", regDMData.isVolatile());
		Assert.assertTrue("RegisterData.isWriteable()", regDMData.isWriteable());
		Assert.assertFalse("RegisterData.isWriteOnce()", regDMData.isWriteOnce());
	}

	@Test
	public void testInternalGetRegisterGroupData() throws Exception {
		Query<IRegisterGroupDMData> query = new Query<IRegisterGroupDMData>() {
			@Override
			protected void execute(final DataRequestMonitor<IRegisterGroupDMData> drm) {
				regService.getModelData(regGroupDMC, drm);
			}
		};
		testLaunch.session.getExecutor().execute(query);
		IRegisterGroupDMData regGroupData = query.get(1, TimeUnit.SECONDS);
		Assert.assertTrue(query.isDone());
		Assert.assertNotNull(regGroupData);
		Assert.assertEquals("RegisterGroupData.getDescription()",
							"Basic Program Execution Registers of x86", regGroupData.getDescription());
		Assert.assertEquals("RegisterGroupData.getName()", "Basic", regGroupData.getName());		
	}

	@Test
	public void coverageInternalWriteBitFieldStringEmptyImplementation() throws Exception {
		Query<Boolean> query = new Query<Boolean>() {
			@Override
			protected void execute(final DataRequestMonitor<Boolean> drm) {
				regService.writeBitField((IBitFieldDMContext)null, (String)"bitFieldValue", (String)"formatID", drm);
			}
		};
		testLaunch.session.getExecutor().execute(query);
		query.get(1, TimeUnit.SECONDS);
		Assert.assertTrue(query.isDone());
	}

	@Test
	public void coverageInternalWriteBitFieldIMnemonicEmptyImplementation() throws Exception {
		Query<Boolean> query = new Query<Boolean>() {
			@Override
			protected void execute(final DataRequestMonitor<Boolean> drm) {
				regService.writeBitField((IBitFieldDMContext)null, (IMnemonic)null, drm);
			}
		};
		testLaunch.session.getExecutor().execute(query);
		query.get(1, TimeUnit.SECONDS);
		Assert.assertTrue(query.isDone());
	}

	private void testRegisterWrites(final Registers regService, final IRegisterDMContext[] regDMCs)
			throws Exception {
		for (IRegisterDMContext regContext : regDMCs) {
			final RegisterDMC regDMC = (RegisterDMC) regContext;
			regService.writeRegister(regDMC, "0000000d", "NATURAL.Format");
			Assert.assertEquals("d", regService.getRegisterValueAsHexString(regDMC));
		}
	}

	private static IRegisterDMContext[] waitForRegisterDMCs(final IRegisterGroupDMContext regGroupDMC,
			final Registers regService) throws Exception {
		final IRegisterDMContext contextsHolder[][] = { null };
		TestUtils.wait(new Condition() {
			public boolean isConditionValid() {
				CompositeDMContext compositeDMC
				  = new CompositeDMContext(new IDMContext[] { testLaunch.threadDMC, regGroupDMC });
				regService.getRegisters(compositeDMC,
						new DataRequestMonitor<IRegisterDMContext[]>(regService.getExecutor(), null) {
					@Override
					protected void handleSuccess() {
						contextsHolder[0] = getData();
					}
				});
				if (contextsHolder[0] != null)
					return true;

				return false;
			}
		});
		return contextsHolder[0];
	}

	private static IRegisterGroupDMContext waitForRegisterGroup(final Registers regService) throws Exception {
		Query<IRegisterGroupDMContext[]> query = new Query<IRegisterGroupDMContext[]>() {
			@Override
			protected void execute(final DataRequestMonitor<IRegisterGroupDMContext[]> drm) {
				regService.getRegisterGroups(testLaunch.threadDMC, drm);
			}
		};
		testLaunch.session.getExecutor().execute(query);

		IRegisterGroupDMContext[] expectedResult = query.get(2, TimeUnit.SECONDS);
		Assert.assertTrue(query.isDone());
		Assert.assertTrue("", 0 < expectedResult.length);
		return expectedResult[0];
	}
}
