/*******************************************************************************
 * 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.ArrayList;
import java.util.Random;

import org.eclipse.cdt.debug.edc.internal.EDCDebugger;
import org.eclipse.cdt.debug.edc.internal.services.dsf.Memory;
import org.eclipse.cdt.debug.edc.services.EDCServicesTracker;
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.model.DsfMemoryBlockRetrieval;
import org.eclipse.cdt.utils.Addr32;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.model.MemoryByte;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class MemoryView extends BaseLaunchTest {

	@Override
	protected boolean getStopAtMain() {
		return true;
	}

	@Before
	public void launch() throws Exception {
		basicLaunch();
	}

	@After
	public void shutdown() {
		TestUtils.shutdownDebugSession(launch, session);
		session = null;
	}

	@Test
	public void testMemoryView() throws Exception {
		TestUtils.waitForUIUpdate(1500);
		final DsfMemoryBlockRetrieval memoryBlock = launch.getMemoryBlockRetrieval();
		assertNotNull(memoryBlock);
		EDCServicesTracker edcTracker
		  = new EDCServicesTracker(EDCDebugger.getBundleContext(), session.getId());
		final Memory mem = edcTracker.getService(Memory.class);
		assertNotNull(edcTracker);

		// Write memory, read memory back and compare
		final Addr32 addr32 = new Addr32(0x405400);
		final byte[] data = new byte[1000];
		new Random().nextBytes(data);

		// Use a Query to synchronize the downstream calls
		Query<MemoryByte[]> query = new Query<MemoryByte[]>() {
			@Override
			protected void execute(final DataRequestMonitor<MemoryByte[]> drm) {
				mem.setMemory(threadDMC, addr32, 0, 1, 1000, data,
						new RequestMonitor(memoryBlock.getExecutor(), drm));
			}
		};
		memoryBlock.getExecutor().execute(query);

		TestUtils.wait(new TestUtils.Condition() {
			public boolean isConditionValid() {
				ArrayList<MemoryByte> buf = new ArrayList<MemoryByte>();
				IStatus memGetStatus = mem.getMemory(threadDMC, addr32, buf, data.length, 1);

				if (memGetStatus.isOK()) {
					for (int i = 0; (i < buf.size()) && (i < data.length); i++) {
						// check each byte
						if (!buf.get(i).isReadable())
							return false;
						if (data[i] != buf.get(i).getValue())
							return false;
					}
				} else
					return false;

				return true;
			}
		});
	}
}
