/*******************************************************************************
 * 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.x86;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.edc.IAddressExpressionEvaluator;
import org.eclipse.cdt.debug.edc.disassembler.IDisassembledInstruction;
import org.eclipse.cdt.debug.edc.disassembler.IDisassembler;
import org.eclipse.cdt.debug.edc.disassembler.IDisassembler.IDisassemblerOptions;
import org.eclipse.cdt.debug.edc.services.AbstractTargetEnvironment;
import org.eclipse.cdt.debug.edc.services.Disassembly;
import org.eclipse.cdt.debug.edc.services.ITargetEnvironment;
import org.eclipse.cdt.debug.edc.symbols.TypeUtils;
import org.eclipse.cdt.debug.edc.x86.disassembler.AddressExpressionEvaluatorX86;
import org.eclipse.cdt.debug.edc.x86.disassembler.DisassemblerX86;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext;
import org.eclipse.cdt.dsf.debug.service.IMemory;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.MemoryByte;

/**
 * {@link ITargetEnvironment} service for x86.
 */
public class TargetEnvironmentX86 extends AbstractTargetEnvironment implements ITargetEnvironment {

	// breakpoint instruction for x86.
	final static byte[] sBreakpointInstruction = { (byte) 0xcc };

	private IDisassembler disassembler = null;

	private IAddressExpressionEvaluator aeEvaluator = null;

	private HashMap<Integer, Integer> basicTypeSizes = null;

	public TargetEnvironmentX86(DsfSession session, ILaunch launch) {
		super(session, new String[] { TargetEnvironmentX86.class.getName() },
				launch);
	}

	public String getArchitecture() {
		return ARCH_X86;
	}

	public byte[] getBreakpointInstruction(IDMContext context, IAddress address) {
		// arguments are ignored.
		return sBreakpointInstruction;
	}

	public void updateBreakpointProperties(IDMContext context, IAddress address, Map<String, Object> properties) {
	}

	public IDisassembler getDisassembler() {
		if (disassembler == null)
			disassembler = new DisassemblerX86(this);

		return disassembler;
	}

	public String getOS() {
		return OS_UNKNOWN;
	}

	public String getPCRegisterID() {
		return "EIP";
	}

	public String getProperty(String propertyKey) {
		return null;
	}

	public boolean isLittleEndian(IDMContext context) {
		return true;
	}

	public int getLongestInstructionLength() {
		// it's said to be 17 bytes...
		return 18;
	}

	public IAddressExpressionEvaluator getAddressExpressionEvaluator() {
		if (aeEvaluator == null)
			aeEvaluator = new AddressExpressionEvaluatorX86();

		return aeEvaluator;
	}

	public Map<Integer, Integer> getBasicTypeSizes() {
		if (this.basicTypeSizes == null) {
			this.basicTypeSizes = new HashMap<Integer, Integer>();
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_CHAR, 1);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_SHORT, 2);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_INT, 4);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_LONG, 4);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_LONG_LONG, 8);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_FLOAT, 4);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_FLOAT_COMPLEX, 8);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_DOUBLE, 8);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_DOUBLE_COMPLEX, 16);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_LONG_DOUBLE, 8);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_LONG_DOUBLE_COMPLEX, 16);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_BOOL, 1);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_BOOL_C9X, 1);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_WCHAR_T, 2);
			this.basicTypeSizes.put(TypeUtils.BASIC_TYPE_POINTER, 4);
		}

		return this.basicTypeSizes;
	}

	public boolean isCharSigned() {
		return true;
	}

	public int getEnumSize() {
		return 4;
	}

	public int getPointerSize() {
		return 4;
	}

	public int getMemoryCacheMinimumBlockSize() {
		/*
		 * Currently for x86 Windows debugger, a non-zero minimum size may crash
		 * the TCF Windows agent. Before that's fixed, we just return 0. See
		 * Javadoc of the API for more.......02/09/10
		 */
		return 0;
	}

	@Override
	public void stepPastGlueCode(final IExecutionDMContext dmc, final IAddress pc,
			final RequestMonitor rm) {
		IMemory memService = getService(IMemory.class);
		IMemoryDMContext mem_dmc = DMContexts.getAncestorOfType(dmc, IMemoryDMContext.class);

		// Glue code in function call in x86:
		// it's just a jmp instruction.

		// We need to get the instruction at the PC. We have to
		// retrieve memory bytes for longest instruction.
		int maxInstLength = getLongestInstructionLength();

		memService.getMemory(mem_dmc, pc, 0, 1, maxInstLength,
								new DataRequestMonitor<MemoryByte[]>(getExecutor(), rm) {
			@Override
			protected void handleSuccess() {
				ByteBuffer codeBuf = Disassembly.translateMemoryBytes(getData(), pc, rm);
				if (codeBuf == null) {
					return;	// rm status set in translateMemoryBytes()
				}

				IDisassemblyDMContext dis_dmc
					= DMContexts.getAncestorOfType(dmc, IDisassemblyDMContext.class);
				Map<String, Object> options = new HashMap<String, Object>();
				options.put(IDisassemblerOptions.ADDRESS_IS_PC, 1);
				IDisassembledInstruction inst;
				try {
					inst = disassembler.disassembleOneInstruction(pc, codeBuf, options, dis_dmc);
				} catch (CoreException e) {
					rm.setStatus(e.getStatus());
					rm.done();
					return;
				}

				final boolean isJump = inst.getJumpToAddress() != null
						&& !inst.getJumpToAddress().isSubroutineAddress();

				if (! isJump)	// not glue code, done.
					rm.done();
				else {
					// Execute a single instruction to step past the glue code
					//
					IRunControl rcService = getService(IRunControl.class);
					rcService.step(dmc, StepType.INSTRUCTION_STEP_INTO, rm);
				}
			}
		});
	}
}
