/*******************************************************************************
 * Copyright (c) 2004, 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
 *     OBEO - fork for stand alone use in Acceleo
 *******************************************************************************/
package org.eclipse.acceleo.model.mtl.resource;

// CHECKSTYLE:OFF
import java.io.IOException;
import java.io.InputStream;

/**
 * Forked from org.eclipse.core
 * 
 * @since 3.1
 */
public class LazyInputStream extends InputStream {
	private int blockCapacity;

	byte[][] blocks = {};

	private int bufferSize;

	private InputStream in;

	private int mark;

	private int offset;

	public LazyInputStream(InputStream in, int blockCapacity) {
		this.in = in;
		this.blockCapacity = blockCapacity;
	}

	@Override
	public int available() throws IOException {
		try {
			return bufferSize - offset + in.available();
		} catch (IOException ioe) {
			throw new LowLevelIOException(ioe);
		}
	}

	private int computeBlockSize(int blockIndex) {
		if (blockIndex < blocks.length - 1) {
			return blockCapacity;
		}
		int blockSize = bufferSize % blockCapacity;
		return blockSize == 0 ? blockCapacity : blockSize;
	}

	private int copyFromBuffer(byte[] userBuffer, int userOffset, int needed) {
		int copied = 0;
		int current = offset / blockCapacity;
		while ((needed - copied) > 0 && current < blocks.length) {
			int blockSize = computeBlockSize(current);
			int offsetInBlock = offset % blockCapacity;
			int availableInBlock = blockSize - offsetInBlock;
			int toCopy = Math.min(availableInBlock, needed - copied);
			System.arraycopy(blocks[current], offsetInBlock, userBuffer, userOffset + copied, toCopy);
			copied += toCopy;
			current++;
			offset += toCopy;
		}
		return copied;
	}

	private void ensureAvailable(long bytesToRead) throws IOException {
		int loadedBlockSize = blockCapacity;
		while (bufferSize < offset + bytesToRead && loadedBlockSize == blockCapacity) {
			try {
				loadedBlockSize = loadBlock();
			} catch (IOException e) {
				throw new LowLevelIOException(e);
			}
			bufferSize += loadedBlockSize;
		}
	}

	// for testing purposes
	protected int getBlockCount() {
		return blocks.length;
	}

	// for testing purposes
	protected int getBufferSize() {
		return bufferSize;
	}

	// for testing purposes
	protected int getMark() {
		return mark;
	}

	// for testing purposes
	protected int getOffset() {
		return offset;
	}

	public boolean isText() {
		return false;
	}

	private int loadBlock() throws IOException {
		// read a block from the underlying stream
		byte[] newBlock = new byte[blockCapacity];
		int readCount = in.read(newBlock);
		if (readCount == -1) {
			return 0;
		}
		// expand blocks array
		byte[][] tmpBlocks = new byte[blocks.length + 1][];
		System.arraycopy(blocks, 0, tmpBlocks, 0, blocks.length);
		blocks = tmpBlocks;
		blocks[blocks.length - 1] = newBlock;
		return readCount;
	}

	@Override
	public synchronized void mark(int readlimit) {
		mark = offset;
	}

	@Override
	public boolean markSupported() {
		return true;
	}

	@Override
	public int read() throws IOException {
		ensureAvailable(1);
		if (bufferSize <= offset) {
			return -1;
		}
		int nextByte = 0xFF & blocks[offset / blockCapacity][offset % blockCapacity];
		offset++;
		return nextByte;
	}

	@Override
	public int read(byte[] b) throws IOException {
		return read(b, 0, b.length);
	}

	@Override
	public int read(byte[] b, int off, int len) throws IOException {
		ensureAvailable(len);
		int copied = copyFromBuffer(b, off, len);
		return copied == 0 ? -1 : copied;
	}

	@Override
	public synchronized void reset() {
		offset = mark;
	}

	public void rewind() {
		mark = 0;
		offset = 0;
	}

	@Override
	public long skip(long toSkip) throws IOException {
		if (toSkip <= 0) {
			return 0;
		}
		ensureAvailable(toSkip);
		long skipped = Math.min(toSkip, bufferSize - offset);
		offset += skipped;
		return skipped;
	}
}
