/*
 * Copyright (C) 2007 The Guava Authors
 * Copyright (C) 2014, Sasa Zivkov <sasa.zivkov@sap.com>, SAP AG and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.eclipse.jgit.util.io;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.eclipse.jgit.internal.JGitText;

/**
 * Wraps a {@link java.io.InputStream}, limiting the number of bytes which can
 * be read.
 *
 * This class was copied and modifed from the Google Guava 16.0. Differently
 * from the original Guava code, when a caller tries to read from this stream
 * past the given limit and the wrapped stream hasn't yet reached its EOF this
 * class will call the limitExceeded method instead of returning EOF.
 *
 * @since 3.3
 */
public abstract class LimitedInputStream extends FilterInputStream {

	private long left;
	/** Max number of bytes to be read from the wrapped stream */
	protected final long limit;
	private long mark = -1;

	/**
	 * Create a new LimitedInputStream
	 *
	 * @param in an InputStream
	 * @param limit max number of bytes to read from the InputStream
	 */
	protected LimitedInputStream(InputStream in, long limit) {
		super(in);
		left = limit;
		this.limit = limit;
	}

	/** {@inheritDoc} */
	@Override
	public int available() throws IOException {
		return (int) Math.min(in.available(), left);
	}

	// it's okay to mark even if mark isn't supported, as reset won't work
	/** {@inheritDoc} */
	@Override
	public synchronized void mark(int readLimit) {
		in.mark(readLimit);
		mark = left;
	}

	/** {@inheritDoc} */
	@Override
	public int read() throws IOException {
		if (left == 0) {
			if (in.available() == 0) {
				return -1;
			}
			limitExceeded();
		}

		int result = in.read();
		if (result != -1) {
			--left;
		}
		return result;
	}

	/** {@inheritDoc} */
	@Override
	public int read(byte[] b, int off, int len) throws IOException {
		if (left == 0) {
			if (in.available() == 0) {
				return -1;
			}
			limitExceeded();
		}

		len = (int) Math.min(len, left);
		int result = in.read(b, off, len);
		if (result != -1) {
			left -= result;
		}
		return result;
	}

	/** {@inheritDoc} */
	@Override
	public synchronized void reset() throws IOException {
		if (!in.markSupported())
			throw new IOException(JGitText.get().unsupportedMark);

		if (mark == -1)
			throw new IOException(JGitText.get().unsetMark);

		in.reset();
		left = mark;
	}

	/** {@inheritDoc} */
	@Override
	public long skip(long n) throws IOException {
		n = Math.min(n, left);
		long skipped = in.skip(n);
		left -= skipped;
		return skipped;
	}

	/**
	 * Called when trying to read past the given {@link #limit} and the wrapped
	 * InputStream {@link #in} hasn't yet reached its EOF
	 *
	 * @throws java.io.IOException
	 *             subclasses can throw an {@link java.io.IOException} when the
	 *             limit is exceeded. The throws java.io.IOException will be
	 *             forwarded back to the caller of the read method which read
	 *             the stream past the limit.
	 */
	protected abstract void limitExceeded() throws IOException;
}
