// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.bridge.io;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;

public class FileRangeInputStream extends InputStream {
	private RandomAccessFile randomAccessFile;
	private long curPos;
	private long endPos; 
	private long fileLength;
	
	public FileRangeInputStream(File file, long startPos, long endPos) throws IOException {
		fileLength = file.length();
		
		if(startPos > fileLength)
			startPos = fileLength;
		
		if(endPos > fileLength)
			endPos = fileLength;
		
		if(startPos > endPos)
			throw new IllegalArgumentException("Invalid file range " + startPos + "-" + endPos);

		this.curPos = startPos;
		this.endPos = endPos;
		randomAccessFile = new RandomAccessFile(file, "r");
		randomAccessFile.seek(startPos);
	}
	
	@Override
	public int available() throws IOException {
		return (int)(endPos - curPos);
	}

	@Override
	public int read() throws IOException {
		if(available() > 0) {
			int value = randomAccessFile.read();
			curPos++;
			return value;
		}
		return -1;
	}
	
	@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 {
		int bytesToRead = Math.min(len, available());
		if(bytesToRead == 0)
			return -1;
		
		int bytesRead = randomAccessFile.read(b, off, bytesToRead);
		if(bytesRead < 0)
			return -1;
		
		curPos += bytesRead;
		return bytesRead;
	}
	
	@Override
	public long skip(long n) throws IOException {
		long skipped = Math.min(n, available());
		randomAccessFile.skipBytes((int)skipped);
		curPos += skipped;
		return skipped;
	}
	
	@Override
	public void close() throws IOException {
		randomAccessFile.close();
	}
}
