/*******************************************************************************
 * Copyright (c) 2006, 2008 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *     WindRiver - Bug 192028 [Memory View] Memory view does not 
 *                 display memory blocks that do not reference IDebugTarget
 *******************************************************************************/

package org.eclipse.debug.internal.ui.elements.adapters;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Vector;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IMemoryBlockExtension;
import org.eclipse.debug.core.model.MemoryByte;
import org.eclipse.debug.internal.ui.DebugUIMessages;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.memory.provisional.AbstractAsyncTableRendering;
import org.eclipse.debug.internal.ui.memory.provisional.MemoryViewPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter;
import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil;
import org.eclipse.debug.internal.ui.views.memory.renderings.MemorySegment;
import org.eclipse.debug.internal.ui.views.memory.renderings.TableRenderingContentDescriptor;
import org.eclipse.debug.ui.memory.IMemoryRendering;

public class MemoryBlockContentAdapter extends AsynchronousContentAdapter {

	// Cache to allow the content provider to comppute change information
	// Cache is taken by copying the lineCache after a suspend event
	// or change event from the the memory block.
	protected Hashtable contentCache;
	
	public MemoryBlockContentAdapter()
	{
		contentCache = new Hashtable();
	}

	protected Object[] getChildren(Object parent, IPresentationContext context)
			throws CoreException {
		
		if (!(parent instanceof IMemoryBlock))
			return new Object[0];
		
		if (!(context instanceof MemoryViewPresentationContext))
			return new Object[0];
		
		MemoryViewPresentationContext memoryViewContext = (MemoryViewPresentationContext)context; 
		IMemoryRendering rendering = memoryViewContext.getRendering();
		
		if (!(rendering instanceof AbstractAsyncTableRendering))
			return new Object[0];
			
		try 
		{
			return getMemoryFromMemoryBlock(memoryViewContext);
		} catch (DebugException e) {
			throw e;
		}			

	}

	protected boolean hasChildren(Object element, IPresentationContext context)
			throws CoreException {
		
		if (context instanceof MemoryViewPresentationContext)
		{
			if (((MemoryViewPresentationContext)context).getRendering() != null)
				return true;
		}
		
		return false;
	}

	protected boolean supportsPartId(String id) {
		return true;
	}
	
	
	private Object[] getMemoryFromMemoryBlock(MemoryViewPresentationContext context) throws DebugException {
		IMemoryBlock memoryBlock = context.getRendering().getMemoryBlock();
		if (memoryBlock instanceof IMemoryBlockExtension)
		{
			return loadContentForExtendedMemoryBlock(context);
		}

		return loadContentForSimpleMemoryBlock(context);
		
	}

	/**
	 * @throws DebugException
	 */
	public Object[] loadContentForSimpleMemoryBlock(MemoryViewPresentationContext context) throws DebugException {
		AbstractAsyncTableRendering rendering = getTableRendering(context);
		if (rendering != null)
		{
			IMemoryBlock memoryBlock = rendering.getMemoryBlock();
			long startAddress = memoryBlock.getStartAddress();
			BigInteger address = BigInteger.valueOf(startAddress);
			long length = memoryBlock.getLength();
			long numLines = length / rendering.getBytesPerLine();
			return getMemoryToFitTable(address, numLines,  context);
		}
		return EMPTY;
	}

	/**
	 * @throws DebugException
	 */
	public Object[] loadContentForExtendedMemoryBlock(MemoryViewPresentationContext context) throws DebugException {
		
		AbstractAsyncTableRendering rendering = getTableRendering(context);
		if (rendering != null)
		{
			TableRenderingContentDescriptor descriptor = (TableRenderingContentDescriptor)rendering.getAdapter(TableRenderingContentDescriptor.class);
			
			if (descriptor == null)
				return new Object[0];
			
			if (descriptor.getNumLines() <= 0)
				return new Object[0];
			
			// calculate top buffered address
			BigInteger loadAddress = descriptor.getLoadAddress();
			if (loadAddress == null)
			{
				loadAddress = new BigInteger("0"); //$NON-NLS-1$
			}
			
			BigInteger mbStart = descriptor.getStartAddress();
			BigInteger mbEnd = descriptor.getEndAddress();
			
			// check that the load address is within range
			if (loadAddress.compareTo(mbStart) < 0 || loadAddress.compareTo(mbEnd) > 0)
			{
				// default load address to memory block base address
				loadAddress = ((IMemoryBlockExtension)descriptor.getMemoryBlock()).getBigBaseAddress();
				descriptor.setLoadAddress(loadAddress);
			}
			
			// if address is still out of range, throw an exception
			if (loadAddress.compareTo(mbStart) < 0 || loadAddress.compareTo(mbEnd) > 0)
			{
				throw new DebugException(DebugUIPlugin.newErrorStatus(DebugUIMessages.TableRenderingContentProvider_0 + loadAddress.toString(16), null));
			}
			
			int addressableUnitsPerLine = rendering.getAddressableUnitPerLine();
			BigInteger bufferStart = loadAddress.subtract(BigInteger.valueOf(descriptor.getPreBuffer()*addressableUnitsPerLine));
			BigInteger bufferEnd = loadAddress.add(BigInteger.valueOf(descriptor.getPostBuffer()*addressableUnitsPerLine));
			bufferEnd = bufferEnd.add(BigInteger.valueOf(descriptor.getNumLines()*addressableUnitsPerLine));
			
			// TODO:  should rely on input to tell us what to load
			// instead of having the content adapter override the setting
			if (descriptor.isDynamicLoad())
			{
				if (bufferStart.compareTo(mbStart) < 0)
					bufferStart = mbStart;
				
				if (bufferEnd.compareTo(mbEnd) > 0)
				{
					bufferEnd = mbEnd;
					
					int numLines = bufferEnd.subtract(bufferStart).divide(BigInteger.valueOf(addressableUnitsPerLine)).intValue();
					if (numLines < descriptor.getNumLines())
					{
						// re-calculate buffer start since we may not have enough lines to popoulate the view
						bufferStart = bufferEnd.subtract(BigInteger.valueOf(descriptor.getNumLines()*addressableUnitsPerLine));
						bufferStart = bufferStart.subtract(BigInteger.valueOf(descriptor.getPreBuffer()*addressableUnitsPerLine));
						
						// if after adjusting buffer start, it goes before the memory block start 
						// address, adjust it back
						if (bufferStart.compareTo(mbStart) < 0)
							bufferStart = mbStart;
					}
				}
				
				// buffer end must be greater than buffer start
				if (bufferEnd.compareTo(bufferStart) <= 0)
					throw new DebugException(DebugUIPlugin.newErrorStatus(DebugUIMessages.TableRenderingContentProvider_1, null));
				
				int numLines = bufferEnd.subtract(bufferStart).divide(BigInteger.valueOf(addressableUnitsPerLine)).intValue()+1;		
				// get stoarage to fit the memory view tab size
				return getMemoryToFitTable(bufferStart, numLines,context);
			}
			else
			{
				if (bufferStart.compareTo(mbStart) < 0)
					bufferStart = mbStart;
				
				if (bufferEnd.compareTo(mbEnd) > 0)
				{
					bufferStart = mbEnd.subtract(BigInteger.valueOf((descriptor.getNumLines()-1)*addressableUnitsPerLine));
					bufferEnd = mbEnd;
					
					// after adjusting buffer start, check if it's smaller than memory block's start address
					if (bufferStart.compareTo(mbStart) < 0)
						bufferStart = mbStart;
				}
				
				// buffer end must be greater than buffer start
				if (bufferEnd.compareTo(bufferStart) <= 0)
					throw new DebugException(DebugUIPlugin.newErrorStatus(DebugUIMessages.TableRenderingContentProvider_2, null));
				
				int numLines = descriptor.getNumLines();
				int bufferNumLines = bufferEnd.subtract(bufferStart).divide(BigInteger.valueOf(addressableUnitsPerLine)).intValue()+1;
				
				if (bufferNumLines < numLines)
					numLines = bufferNumLines;
				
				// get stoarage to fit the memory view tab size
				return getMemoryToFitTable(bufferStart, numLines,  context);
			}
		}
		return EMPTY;
	}
	
	/**
	 * Get memory to fit table
	 * @param startingAddress
	 * @param numberOfLines
	 * @param updateDelta
	 * @throws DebugException
	 */
	public Object[]  getMemoryToFitTable(BigInteger startAddress, long numberOfLines, MemoryViewPresentationContext context) throws DebugException
	{
		AbstractAsyncTableRendering tableRendering = getTableRendering(context);	
		if (tableRendering == null)
		{
			DebugException e = new DebugException(DebugUIPlugin.newErrorStatus(DebugUIMessages.MemoryViewContentProvider_Unable_to_retrieve_content, null));
			throw e;
		}
		
		TableRenderingContentDescriptor descriptor = (TableRenderingContentDescriptor)tableRendering.getAdapter(TableRenderingContentDescriptor.class);
		if(descriptor == null)
			return new Object[0];
		
		// do not ask for memory from memory block if the debug target
		// is already terminated
		IDebugTarget target = descriptor.getMemoryBlock().getDebugTarget();
		
		// check for null target to not calculate and retrieve memory for standard debug model
		if (target != null && (target.isDisconnected() || target.isTerminated()))
			return new Object[0];
		
		boolean error = false;
		DebugException dbgEvt = null;
		
		String adjustedAddress = startAddress.toString(16);

		// align to the closest boundary based on addressable size per line
		if (descriptor.isAlignAddressToBoundary() &&  descriptor.getMemoryBlock() instanceof IMemoryBlockExtension)
		{
			startAddress = MemoryViewUtil.alignToBoundary(startAddress, tableRendering.getAddressableUnitPerLine());
		}

		IMemoryBlockExtension extMemoryBlock = null;
		MemoryByte[] memoryBuffer = null;
		
		long reqNumBytes = 0;
		try
		{
			
			if (descriptor.getMemoryBlock() instanceof IMemoryBlockExtension)
			{
				reqNumBytes = tableRendering.getBytesPerLine() * numberOfLines;
				// get memory from memory block
				extMemoryBlock = (IMemoryBlockExtension) descriptor.getMemoryBlock();
				
				long reqNumberOfUnits = tableRendering.getAddressableUnitPerLine() * numberOfLines;
						
				memoryBuffer =	extMemoryBlock.getBytesFromAddress(startAddress,	reqNumberOfUnits);
		
				if(memoryBuffer == null)
				{
					DebugException e = new DebugException(DebugUIPlugin.newErrorStatus(DebugUIMessages.MemoryViewContentProvider_Unable_to_retrieve_content, null));
					throw e;
				}
			}
			else 
			{				
				// get memory from memory block
				byte[] memory = descriptor.getMemoryBlock().getBytes();
				
				if (memory == null)
				{
					DebugException e = new DebugException(DebugUIPlugin.newErrorStatus(DebugUIMessages.MemoryViewContentProvider_Unable_to_retrieve_content, null));	
					throw e;					
				}
				
				int prefillNumBytes = 0;
				
				// number of bytes need to prefill
				if (!startAddress.toString(16).endsWith("0")) //$NON-NLS-1$
				{
					adjustedAddress = startAddress.toString(16).substring(0, adjustedAddress.length() - 1);
					adjustedAddress += "0"; //$NON-NLS-1$
					BigInteger adjustedStart = new BigInteger(adjustedAddress, 16);
					prefillNumBytes = startAddress.subtract(adjustedStart).intValue();
					startAddress = adjustedStart;
				}
				reqNumBytes = descriptor.getMemoryBlock().getLength() + prefillNumBytes;
				
				// figure out number of dummy bytes to append
				while (reqNumBytes % tableRendering.getBytesPerLine() != 0)
				{
					reqNumBytes ++;
				}
				
				numberOfLines = reqNumBytes / tableRendering.getBytesPerLine();
				
				// create memory byte for IMemoryBlock
				memoryBuffer = new MemoryByte[(int)reqNumBytes];
				
				// prefill buffer to ensure double-word alignment
				for (int i=0; i<prefillNumBytes; i++)
				{
					MemoryByte tmp = new MemoryByte();
					tmp.setValue((byte)0);
					tmp.setWritable(false);
					tmp.setReadable(false);
					tmp.setEndianessKnown(false);
					memoryBuffer[i] = tmp;
				}
				
				// fill buffer with memory returned by debug adapter
				int j = prefillNumBytes; 							// counter for memoryBuffer
				for (int i=0; i<memory.length; i++)
				{
					MemoryByte tmp = new MemoryByte();
					tmp.setValue(memory[i]);
					tmp.setReadable(true);
					tmp.setWritable(true);
					tmp.setEndianessKnown(false);
					memoryBuffer[j] = tmp;
					j++;
				}
				
				// append to buffer to fill up the entire line
				for (int i=j; i<memoryBuffer.length; i++)
				{
					MemoryByte tmp = new MemoryByte();
					tmp.setValue((byte)0);
					tmp.setWritable(false);
					tmp.setReadable(false);
					tmp.setEndianessKnown(false);
					memoryBuffer[i] = tmp;
				}
			}
		}
		catch (DebugException e)
		{
			memoryBuffer = makeDummyContent(numberOfLines, tableRendering.getBytesPerLine());
			
			// finish creating the content provider before throwing an event
			error = true; 
			dbgEvt = e;
		}
		catch (Throwable e)
		{
			// catch all errors from this process just to be safe
			memoryBuffer = makeDummyContent(numberOfLines, tableRendering.getBytesPerLine());
			
			// finish creating the content provider before throwing an event
			error = true; 
			dbgEvt = new DebugException(DebugUIPlugin.newErrorStatus(e.getMessage(), e));
		}
		
		// if debug adapter did not return enough memory, create dummy memory
		if (memoryBuffer.length < reqNumBytes)
		{
			ArrayList newBuffer = new ArrayList();
			
			for (int i=0; i<memoryBuffer.length; i++)
			{
				newBuffer.add(memoryBuffer[i]);
			}
			
			for (int i=memoryBuffer.length; i<reqNumBytes; i++)
			{
				MemoryByte mb = new MemoryByte();
				mb.setReadable(false);
				mb.setWritable(false);
				mb.setEndianessKnown(false);
				newBuffer.add(mb);
			}
			
			memoryBuffer = (MemoryByte[])newBuffer.toArray(new MemoryByte[newBuffer.size()]);
			
		}

		boolean manageDelta = true;
		
		// If change information is not managed by the memory block
		// The view tab will manage it and calculate delta information
		// for its content cache.
		if (descriptor.getMemoryBlock() instanceof IMemoryBlockExtension)
		{
			manageDelta = !((IMemoryBlockExtension)descriptor.getMemoryBlock()).supportsChangeManagement();
		}
			
		if (error){
			throw dbgEvt;
		}
		
		// put memory information into MemoryViewLine
		return organizeLines(numberOfLines, memoryBuffer, startAddress, manageDelta, context);
		

	}

	private Object[] organizeLines(long numberOfLines,  MemoryByte[] memoryBuffer, BigInteger address, boolean manageDelta, MemoryViewPresentationContext context) 
	{
		Vector lineCache = new Vector();
		IMemoryRendering rendering = context.getRendering();
		if (!(rendering instanceof AbstractAsyncTableRendering))
			return lineCache.toArray();
		
		AbstractAsyncTableRendering tableRendering = (AbstractAsyncTableRendering)rendering;
		int addressableUnit = tableRendering.getBytesPerLine()/tableRendering.getAddressableSize();
		
		for (int i = 0; i < numberOfLines; i++)
		{   
			int bytesPerLine = tableRendering.getBytesPerLine();
			MemoryByte[] memory = new MemoryByte[bytesPerLine];
			
			// counter for memory, starts from 0 to number of bytes per line
			int k = 0;
			// j is the counter for memArray, memory returned by debug adapter
			for (int j = i * bytesPerLine;
				j < i * bytesPerLine + bytesPerLine;
				j++)
			{
				
				byte changeFlag = memoryBuffer[j].getFlags();
				if (manageDelta)
				{
					// turn off both change and known bits to make sure that
					// the change bits returned by debug adapters do not take
					// any effect
					
					changeFlag |= MemoryByte.HISTORY_KNOWN;
					changeFlag ^= MemoryByte.HISTORY_KNOWN;
					
					changeFlag |= MemoryByte.CHANGED;
					changeFlag ^= MemoryByte.CHANGED;
				}
				
				MemoryByte newByteObj = new MemoryByte(memoryBuffer[j].getValue(), changeFlag);
				memory[k] =  newByteObj;
				k++;
			}
			
			MemorySegment newLine = new MemorySegment(address, memory, addressableUnit);
			lineCache.add(newLine);
			address = address.add(BigInteger.valueOf(addressableUnit));
		}
		return lineCache.toArray();
	}
	
	/**
	 * @param numberOfLines
	 * @return an array of dummy MemoryByte
	 */
	private MemoryByte[] makeDummyContent(long numberOfLines, int bytesPerLine) {
		MemoryByte[] memoryBuffer;
		// make up dummy memory, needed for recovery in case the debug adapter
		// is capable of retrieving memory again

		int numBytes = (int)(bytesPerLine * numberOfLines);
		memoryBuffer = new MemoryByte[numBytes];
		
		for (int i=0; i<memoryBuffer.length; i++){
			memoryBuffer[i] = new MemoryByte();
			memoryBuffer[i].setValue((byte)0);
			memoryBuffer[i].setWritable(false);
			memoryBuffer[i].setReadable(false);
			memoryBuffer[i].setEndianessKnown(false);
		}
		return memoryBuffer;
	}
	
	protected AbstractAsyncTableRendering getTableRendering(MemoryViewPresentationContext context)
	{
		IMemoryRendering memRendering = context.getRendering();
		if (memRendering != null && memRendering instanceof AbstractAsyncTableRendering)
		{
			return (AbstractAsyncTableRendering)memRendering;
		}
		return null;
	}
}
