/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.debug.internal.ui.views.memory.renderings;

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

import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IDebugElement;
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.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.Viewer;

/**
 * Content provider for MemoryViewTab
 * 
 * @since 3.0
 */
public class TableRenderingContentProvider extends BasicDebugViewContentProvider {
	
	private static final String PREFIX = "MemoryViewContentProvider."; //$NON-NLS-1$
	private static final String UNABLE_TO_RETRIEVE_CONTENT = PREFIX + "Unable_to_retrieve_content"; //$NON-NLS-1$
		
	// cached information
	protected Vector lineCache;
	
	// keeps track of all memory line ever retrieved
	// allow us to compare and compute deltas
	protected Hashtable contentCache;
	
	private BigInteger fBufferTopAddress;
	
	private TableRenderingContentInput fInput;
	
	/**
	 * @param memoryBlock
	 * @param newTab
	 */
	public TableRenderingContentProvider()
	{
		lineCache = new Vector();
		contentCache = new Hashtable();
			
		DebugPlugin.getDefault().addDebugEventListener(this);
	}
	
	/**
	 * @param viewer
	 */
	public void setViewer(StructuredViewer viewer)
	{
		fViewer = viewer;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
	 */
	public void inputChanged(Viewer v, Object oldInput, Object newInput) {
		try {
			if (newInput instanceof TableRenderingContentInput)
			{
				fInput = (TableRenderingContentInput)newInput;
				if (fInput.getMemoryBlock() instanceof IMemoryBlockExtension)
					loadContentForExtendedMemoryBlock();
				else
					loadContentForSimpleMemoryBlock();
				
				// tell rendering to display table if the loading is successful
				fInput.getMemoryRendering().displayTable();
			}
		} catch (DebugException e) {
			DebugUIPlugin.log(e.getStatus());
			fInput.getMemoryRendering().displayError(e);
		}
	}

	public void dispose() {

		// fTabItem disposed by view tab
		
		DebugPlugin.getDefault().removeDebugEventListener(this);		
		
		super.dispose();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
	 */
	public Object[] getElements(Object parent) {

		// if cache is empty, get memory
		if (lineCache.isEmpty()) { 
		
			try {
				IMemoryBlock memoryBlock = fInput.getMemoryBlock();
				if (memoryBlock instanceof IMemoryBlockExtension)
				{
					loadContentForExtendedMemoryBlock();
					fInput.getMemoryRendering().displayTable();
				}
				else
				{
					loadContentForSimpleMemoryBlock();
					fInput.getMemoryRendering().displayTable();
				}
			} catch (DebugException e) {
				DebugUIPlugin.log(e.getStatus());
				fInput.getMemoryRendering().displayError(e);
				return lineCache.toArray();
			}
		}
		return lineCache.toArray();
	}

	/**
	 * @throws DebugException
	 */
	private void loadContentForSimpleMemoryBlock() throws DebugException {
		// get as much memory as the memory block can handle
		fInput.setPreBuffer(0);
		fInput.setPostBuffer(0);
		fInput.setDefaultBufferSize(0);
		long startAddress = fInput.getMemoryBlock().getStartAddress();
		BigInteger address = BigInteger.valueOf(startAddress);
		long length = fInput.getMemoryBlock().getLength();
		long numLines = length / fInput.getMemoryRendering().getBytesPerLine();
		getMemoryToFitTable(address, numLines, fInput.isUpdateDelta());
	}

	/**
	 * @throws DebugException
	 */
	private void loadContentForExtendedMemoryBlock() throws DebugException {
		// calculate top buffered address
		BigInteger address = fInput.getStartingAddress();
		if (address == null)
		{
			address = new BigInteger("0"); //$NON-NLS-1$
		}
		BigInteger bigInt = address;
		if (bigInt.compareTo(BigInteger.valueOf(32)) <= 0) {
			fInput.setPreBuffer(0);
		} else {
			fInput.setPreBuffer(bigInt.divide(BigInteger.valueOf(32)).min(BigInteger.valueOf(fInput.getDefaultBufferSize())).intValue());
		}
		int addressibleUnit = fInput.getMemoryRendering().getAddressibleUnitPerLine();
		address = bigInt.subtract(BigInteger.valueOf(addressibleUnit*fInput.getPostBuffer()));
		
		if (address.compareTo(BigInteger.valueOf(0)) < 0)
			address = BigInteger.valueOf(0);
		
		int numLines = fInput.getNumVisibleLines()+fInput.getPostBuffer()+fInput.getPostBuffer();
		
		// get stoarage to fit the memory view tab size
		getMemoryToFitTable(address, numLines, fInput.isUpdateDelta());
	}
	
	/**
	 * @return the memroy block
	 */
	public IMemoryBlock getMemoryBlock() {
		return fInput.getMemoryBlock();
	}
	
	/**
	 * Get memory to fit table
	 * @param startingAddress
	 * @param numberOfLines
	 * @param updateDelta
	 * @throws DebugException
	 */
	public void getMemoryToFitTable(BigInteger startingAddress, long numberOfLines, boolean updateDelta) throws DebugException
	{
		// do not ask for memory from memory block if the debug target
		// is already terminated
		IDebugTarget target = fInput.getMemoryBlock().getDebugTarget();
		
		if (target.isDisconnected() || target.isTerminated())
			return;
		
		boolean error = false;
		DebugException dbgEvt = null;
		
		// calculate address size
		String adjustedAddress = startingAddress.toString(16);
		
		int addressSize = getAddressSize(startingAddress);
		
		int addressLength = addressSize * IInternalDebugUIConstants.CHAR_PER_BYTE;

		// align starting address with double word boundary
		if (fInput.getMemoryBlock() instanceof IMemoryBlockExtension)
		{
			if (!adjustedAddress.endsWith("0")) //$NON-NLS-1$
			{
				adjustedAddress = adjustedAddress.substring(0, adjustedAddress.length() - 1);
				adjustedAddress += "0"; //$NON-NLS-1$
				startingAddress = new BigInteger(adjustedAddress, 16);
			}
		}

		IMemoryBlockExtension extMemoryBlock = null;
		MemoryByte[] memoryBuffer = null;
		
		String paddedString = DebugUIPlugin.getDefault().getPreferenceStore().getString(IDebugPreferenceConstants.PREF_PADDED_STR);
		
		long reqNumBytes = 0;
		try
		{
			if (fInput.getMemoryBlock() instanceof IMemoryBlockExtension)
			{
				reqNumBytes = fInput.getMemoryRendering().getBytesPerLine() * numberOfLines;
				// get memory from memory block
				extMemoryBlock = (IMemoryBlockExtension) fInput.getMemoryBlock();
				
				long reqNumberOfUnits = fInput.getMemoryRendering().getAddressibleUnitPerLine() * numberOfLines;
				
				memoryBuffer =	extMemoryBlock.getBytesFromAddress(startingAddress,	reqNumberOfUnits);
				
				if(memoryBuffer == null)
				{
					DebugException e = new DebugException(DebugUIPlugin.newErrorStatus(DebugUIMessages.getString(UNABLE_TO_RETRIEVE_CONTENT), null));
					throw e;
				}
			}
			else
			{
				// get memory from memory block
				byte[] memory = fInput.getMemoryBlock().getBytes();
				
				if (memory == null)
				{
					DebugException e = new DebugException(DebugUIPlugin.newErrorStatus(DebugUIMessages.getString(UNABLE_TO_RETRIEVE_CONTENT), null));	
					throw e;					
				}
				
				int prefillNumBytes = 0;
				
				// number of bytes need to prefill
				if (!startingAddress.toString(16).endsWith("0")) //$NON-NLS-1$
				{
					adjustedAddress = startingAddress.toString(16).substring(0, adjustedAddress.length() - 1);
					adjustedAddress += "0"; //$NON-NLS-1$
					BigInteger adjustedStart = new BigInteger(adjustedAddress, 16);
					prefillNumBytes = startingAddress.subtract(adjustedStart).intValue();
					startingAddress = adjustedStart;
				}
				reqNumBytes = memory.length + prefillNumBytes;
				
				// figure out number of dummy bytes to append
				while (reqNumBytes % fInput.getMemoryRendering().getBytesPerLine() != 0)
				{
					reqNumBytes ++;
				}
				
				numberOfLines = reqNumBytes / fInput.getMemoryRendering().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.setReadonly(true);
					tmp.setValid(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.setValid(true);
					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.setReadonly(true);
					tmp.setValid(false);
					memoryBuffer[i] = tmp;
				}
			}
		}
		catch (DebugException e)
		{
			memoryBuffer = makeDummyContent(numberOfLines);
			
			// 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);
			
			// finish creating the content provider before throwing an event
			error = true; 
			dbgEvt = new DebugException(DebugUIPlugin.newErrorStatus(e.getMessage(), e));
			DebugUIPlugin.log(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++)
			{
				byte value = 0;
				byte flags = 0;
				flags |= MemoryByte.READONLY;
				newBuffer.add(new MemoryByte(value, flags));
			}
			
			memoryBuffer = (MemoryByte[])newBuffer.toArray(new MemoryByte[newBuffer.size()]);
			
		}
		
		// clear line cacheit'
		if (!lineCache.isEmpty())
		{
			lineCache.clear();
		}
		String address = startingAddress.toString(16);
		// save address of the top of buffer
		fBufferTopAddress = startingAddress;
		
		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 (fInput.getMemoryBlock() instanceof IMemoryBlockExtension)
		{
			manageDelta = !((IMemoryBlockExtension)fInput.getMemoryBlock()).supportsChangeManagement();
		}
			
		// put memory information into MemoryViewLine
		for (int i = 0; i < numberOfLines; i++)
		{ //chop the raw memory up 
			String tmpAddress = address.toUpperCase();
			if (tmpAddress.length() < addressLength)
			{
				for (int j = 0; tmpAddress.length() < addressLength; j++)
				{
					tmpAddress = "0" + tmpAddress; //$NON-NLS-1$
				}
			}
			MemoryByte[] memory = new MemoryByte[fInput.getMemoryRendering().getBytesPerLine()];
			boolean isMonitored = true;
			
			// 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 * fInput.getMemoryRendering().getBytesPerLine();
				j < i * fInput.getMemoryRendering().getBytesPerLine() + fInput.getMemoryRendering().getBytesPerLine();
				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.KNOWN;
					changeFlag ^= MemoryByte.KNOWN;
					
					changeFlag |= MemoryByte.CHANGED;
					changeFlag ^= MemoryByte.CHANGED;
				}
				
				MemoryByte newByteObj = new MemoryByte(memoryBuffer[j].getValue(), changeFlag);
				memory[k] =  newByteObj;
				k++;
				
				
				if (!manageDelta)
				{
					// If the byte is marked as unknown, the line is not monitored
					if (!memoryBuffer[j].isKnown())
					{
						isMonitored = false;
					}
				}
			}
			
			TableRenderingLine newLine = new TableRenderingLine(tmpAddress, memory, lineCache.size(), paddedString);
			
			TableRenderingLine oldLine = (TableRenderingLine)contentCache.get(newLine.getAddress());
			
			if (manageDelta)
			{
				if (oldLine != null)
					newLine.isMonitored = true;
				else
					newLine.isMonitored = false;
			}
			else
			{
				// check the byte for information
				newLine.isMonitored = isMonitored;
			}
			
			// calculate delta info for the memory view line
			if (manageDelta && !fInput.getMemoryRendering().isDisplayingError())
			{
				if (updateDelta)
				{
					if (oldLine != null)
					{
						newLine.markDeltas(oldLine);
					}
				}
				else
				{
					if (oldLine != null)
					{
						// deltas can only be reused if the line has not been changed
						// otherwise, force a refresh
						if (newLine.isLineChanged(oldLine))
						{
							newLine.markDeltas(oldLine);
						}
						else
						{
							newLine.copyDeltas(oldLine);
						}
					}
				}
			}
			else if (manageDelta && fInput.getMemoryRendering().isDisplayingError())
			{
				// show as unmonitored if the view tab is previoulsy displaying error
				newLine.isMonitored = false;
			}
			lineCache.add(newLine);
			
			// increment row address
			BigInteger bigInt = new BigInteger(address, 16);
			int addressibleUnit = fInput.getMemoryRendering().getBytesPerLine()/fInput.getMemoryRendering().getAddressibleSize();
			address = bigInt.add(BigInteger.valueOf(addressibleUnit)).toString(16);
		}
		
		if (error){
			throw dbgEvt;
		}
	}
	
	/**
	 * @param numberOfLines
	 * @return an array of dummy MemoryByte
	 */
	private MemoryByte[] makeDummyContent(long numberOfLines) {
		MemoryByte[] memoryBuffer;
		// make up dummy memory, needed for recovery in case the debug adapter
		// is capable of retrieving memory again

		int numBytes = (int)(fInput.getMemoryRendering().getBytesPerLine() * numberOfLines);
		memoryBuffer = new MemoryByte[numBytes];
		
		for (int i=0; i<memoryBuffer.length; i++){
			memoryBuffer[i] = new MemoryByte();
			memoryBuffer[i].setValue((byte)0);
			memoryBuffer[i].setReadonly(true);
		}
		return memoryBuffer;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.internal.views.BasicDebugViewContentProvider#doHandleDebugEvent(org.eclipse.debug.core.DebugEvent)
	 */
	protected void doHandleDebugEvent(DebugEvent event) {
		
		// do nothing if the debug event did not come from a debug element comes from non-debug element
		if (!(event.getSource() instanceof IDebugElement))
			return;
		
		IDebugElement src = (IDebugElement)event.getSource();
		
		// if a debug event happens from the memory block
		// invoke contentChanged to get content of the memory block updated
		if (event.getKind() == DebugEvent.CHANGE && event.getSource() == fInput.getMemoryBlock())
		{
			if (event.getDetail() == DebugEvent.STATE){
				fInput.getMemoryRendering().updateLabels();
			}
			else
			{	
				updateContent();
			}
		}
		
		// if the suspend evnet happens from the debug target that the blocked
		// memory block belongs to
		if (event.getKind() == DebugEvent.SUSPEND && src.getDebugTarget() == fInput.getMemoryBlock().getDebugTarget())
		{	
			updateContent();
		}

	}
	
	/**
	 * Update content of the view tab if the content of the memory block has changed
	 * or if its base address has changed
	 * Update will not be performed if the memory block has not been changed or
	 * if the view tab is disabled.
	 */
	public void updateContent()
	{
		IDebugTarget dt = fInput.getMemoryBlock().getDebugTarget();
		
		// no need to update if debug target is disconnected or terminated
		if (dt.isDisconnected() || dt.isTerminated())
		{
			return;
		}
		
		// cache content before getting new ones
		TableRenderingLine[] lines =(TableRenderingLine[]) lineCache.toArray(new TableRenderingLine[lineCache.size()]);
		if (contentCache != null)
		{
			contentCache.clear();
		}
		
		//do not handle event if the rendering is not visible
		if (!fInput.getMemoryRendering().isVisible())
			 return;
		
		// use existing lines as cache is the rendering is not currently displaying
		// error.  Otherwise, leave contentCache empty as we do not have updated
		// content.
		if (!fInput.getMemoryRendering().isDisplayingError())
		{
			for (int i=0; i<lines.length; i++)
			{
				contentCache.put(lines[i].getAddress(), lines[i]);
				lines[i].isMonitored = true;
			}
		}

		// reset all the deltas currently stored in contentCache
		// This will ensure that changes will be recomputed when user scrolls
		// up or down the memory view.		
		resetDeltas();
		fInput.getMemoryRendering().refresh();
		
	}

	/**
	 * @return buffer's top address
	 */
	public BigInteger getBufferTopAddress()
	{
		return fBufferTopAddress;
	}
	
	/**
	 * Calculate address size of the given address
	 * @param address
	 * @return size of address from the debuggee
	 */
	public int getAddressSize(BigInteger address)
	{
		// calculate address size
		 String adjustedAddress = address.toString(16);
		
		 int addressSize = 0;
		 if (fInput.getMemoryBlock() instanceof IMemoryBlockExtension)
		 {
			 addressSize = ((IMemoryBlockExtension)fInput.getMemoryBlock()).getAddressSize();
		 }
		
		 // handle IMemoryBlock and invalid address size returned by IMemoryBlockExtension
		 if (addressSize <= 0)
		 {
			 if (adjustedAddress.length() > 8)
			 {
				 addressSize = 8;
			 }
			 else
			 {
				 addressSize = 4;
			 }			
		 }		
		 
		 return addressSize;
	}
	
	/**
	 * @return base address of memory block
	 */
	public BigInteger getContentBaseAddress()
	{
		return fInput.getContentBaseAddress(); 
	}
	
	/**
	 * Clear all delta information in the lines
	 */
	public void resetDeltas()
	{
		Enumeration enumeration = contentCache.elements();
		
		while (enumeration.hasMoreElements())
		{
			TableRenderingLine line = (TableRenderingLine)enumeration.nextElement();
			line.unmarkDeltas();
		}
	}
	
	/**
	 * Check if address is out of buffered range
	 * @param address
	 * @return true if address is out of bufferred range, false otherwise
	 */
	public boolean isAddressOutOfRange(BigInteger address)
	{
		if (lineCache != null)
		{
			TableRenderingLine first = (TableRenderingLine)lineCache.firstElement();
			TableRenderingLine last = (TableRenderingLine) lineCache.lastElement();
			
			if (first == null ||last == null)
				return true;
			
			BigInteger startAddress = new BigInteger(first.getAddress(), 16);
			BigInteger lastAddress = new BigInteger(last.getAddress(), 16);
			int addressibleUnit = fInput.getMemoryRendering().getAddressibleUnitPerLine();
			lastAddress = lastAddress.add(BigInteger.valueOf(addressibleUnit));
			
			if (startAddress.compareTo(address) <= 0 &&
				lastAddress.compareTo(address) >= 0)
			{
				return false;
			}
			return true;
		}
		return true;
	}
	
	public void clearContentCache()
	{
		contentCache.clear();
	}
}
