/*
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/

package org.eclipse.cdt.debug.edc.internal;

import java.nio.BufferUnderflowException;
import java.nio.ByteOrder;

import org.eclipse.cdt.debug.edc.IStreamBuffer;

/**
 * 
 */
public abstract class StreamBufferBase implements IStreamBuffer {
	/* must be a power of 2 */
	public static final int BUFFER_SIZE = 4096;

	private static double LN_2 = 0.0;
	private static double mathLogOf2() {
		if (0.0 == LN_2) {
			LN_2 = Math.log(2);
		}
		return LN_2;
	}

	/**
	 * get a smaller buffer size when capacity < 4096
	 * EXTENSION: go faster using bitshift operations.
	 * @return either BUFFER_SIZE or a smaller power of 2 that is 
	 * 			larger than the sourceCapacity.
	 */
	private int getBufferSize() {
		if (sourceCapacity >= BUFFER_SIZE) {
			return BUFFER_SIZE;
		}
		return 1 << (int)Math.ceil(Math.log(sourceCapacity)/mathLogOf2());
	}

	protected ByteOrder order;
	
	// absolute
	private long position;
	// absolute
	private long sourceCapacity;

	private byte[] buffer;
	// absolute source position in buffer[0]
	private long sourceOffset;
	// absolute source position in buffer[buffer.length]
	private long sourceLimit;
	
	// offset from source to position
	private final long baseOffset;
	
	/**
	 * Create a buffer over some source content
	 * @param order native byte order of content
	 * @param baseOffset base offset from source to this buffer
	 * @param capacity total size of the source (from baseOffset)
	 */
	public StreamBufferBase(ByteOrder order, long baseOffset, long capacity) {
		this.order = order;
		this.baseOffset = baseOffset;
		this.position = 0;
		this.sourceCapacity = capacity;

		this.buffer = new byte[getBufferSize()];
		this.sourceOffset = 0;
		this.sourceLimit = 0;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return getClass().getSimpleName() +  " pos="+position() + " of "+ capacity() + " base="+ baseOffset; //$NON-NLS-N$ //$NON-NLS-2$ //$NON-NLS-3$
	}
	
	/**
	 * Fetch a page of content from the buffer.
	 * @param buffer the buffer
	 * @param sourceOffset absolute offset in original content
	 * @throws BufferUnderflowException
	 */
	protected abstract void fetchPage(byte[] buffer, long sourceOffset, int count);
	
	protected abstract IStreamBuffer createSubBuffer(long offset, long size);
	

	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#wrapSubsection(int)
	 */
	public IStreamBuffer wrapSubsection(long size) {
		long availableSize = capacity() - position();
		if (availableSize < size)
			size = availableSize;
		return createSubBuffer(position() + baseOffset, size);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#capacity()
	 */
	public long capacity() {
		return sourceCapacity;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#hasRemaining()
	 */
	public boolean hasRemaining() {
		return position < sourceCapacity;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#remaining()
	 */
	public long remaining() {
		return sourceCapacity - position;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#position()
	 */
	public long position() {
		return position;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#position(int)
	 */
	public IStreamBuffer position(long newPosition) {
		if (newPosition < 0 || newPosition > sourceCapacity)
			throw new IllegalArgumentException(newPosition + " not in 0.."+ sourceCapacity);
		
		this.position = newPosition;
		return this;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#get(byte[], int, int)
	 */
	public IStreamBuffer get(byte[] dst, int offset, int length) {
		// read page-by-page if possible
		while (length > 0) {
			if (needFetch())
				refetch();
			
			int left = (int) Math.min(sourceLimit - position, length);
			if (left > 0) {
				System.arraycopy(buffer, (int) (position - sourceOffset), dst, offset, left);
				offset += left;
				position += left;
				length -= left;
			} else {
				break;
			}
		}
		return this;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#get(byte[])
	 */
	public IStreamBuffer get(byte[] dst) {
		return get(dst, 0, dst.length);
	}

	/**
	 * Fill memory buffer from source
	 */
	protected void refetch() {
		long newSourceOffset = position - (position & buffer.length - 1);
		if (newSourceOffset < 0)
			throw new BufferUnderflowException();
		if (newSourceOffset >= sourceCapacity)
			throw new BufferUnderflowException();
		
		int toFetch = (int) Math.min(sourceCapacity - newSourceOffset, buffer.length);
		fetchPage(buffer, newSourceOffset + baseOffset, toFetch);
		sourceOffset = newSourceOffset;
		sourceLimit = sourceOffset + toFetch;
	}
	
	protected final boolean needFetch() {
		return (position < sourceOffset || position >= sourceLimit);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#get()
	 */
	public byte get() {
		if (needFetch()) 
			refetch();
		
		if (position < sourceCapacity)
			return buffer[(int)((position++) - sourceOffset)];
		else
			throw new BufferUnderflowException();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#getChar()
	 */
	public char getChar() {
		return (char) getShort();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#getShort()
	 */
	public short getShort() {
		int a = get() & 0xff;
		int b = get() & 0xff;
		if (order == ByteOrder.LITTLE_ENDIAN)
			return (short) (a | (b << 8));
		else
			return (short) (b | (a << 8));
	}

	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#getInt()
	 */
	public int getInt() {
		int a = getShort() & 0xffff;
		int b = getShort() & 0xffff;
		if (order == ByteOrder.LITTLE_ENDIAN)
			return a | (b << 16);
		else
			return b | (a << 16);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#getLong()
	 */
	public long getLong() {
		long a = getInt();
		long b = getInt();
		if (order == ByteOrder.LITTLE_ENDIAN)
			return a | (b << 32);
		else
			return b | (a << 32);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.IStreamBuffer#skip(long)
	 */
	public IStreamBuffer skip(long amount) {
		return position(position() + amount);
	}
	
	public ByteOrder getOrder() {
		return order;
	}
	public void setOrder(ByteOrder order) {
		this.order = order;
	}
}
