/*
 * Copyright (C) 2010, 2013 Marc Strapetz <marc.strapetz@syntevo.com>
 * Copyright (C) 2015, Ivan Motsch <ivan.motsch@bsiag.com> 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.IOException;
import java.io.InputStream;

import org.eclipse.jgit.diff.RawText;

/**
 * An InputStream that normalizes CRLF to LF.
 *
 * Existing single CR are not changed to LF, but retained as is.
 *
 * Optionally, a binary check on the first 8000 bytes is performed and in case
 * of binary files, canonicalization is turned off (for the complete file).
 * <p>
 * This is the former EolCanonicalizingInputStream with a new name in order to
 * have same naming for all LF / CRLF streams
 *
 * @since 4.3
 */
public class AutoLFInputStream extends InputStream {
	private final byte[] single = new byte[1];

	private final byte[] buf = new byte[8096];

	private final InputStream in;

	private int cnt;

	private int ptr;

	private boolean isBinary;

	private boolean detectBinary;

	private boolean abortIfBinary;

	/**
	 * A special exception thrown when {@link AutoLFInputStream} is told to
	 * throw an exception when attempting to read a binary file. The exception
	 * may be thrown at any stage during reading.
	 *
	 * @since 3.3
	 */
	public static class IsBinaryException extends IOException {
		private static final long serialVersionUID = 1L;

		IsBinaryException() {
			super();
		}
	}

	/**
	 * Creates a new InputStream, wrapping the specified stream
	 *
	 * @param in
	 *            raw input stream
	 * @param detectBinary
	 *            whether binaries should be detected
	 * @since 2.0
	 */
	public AutoLFInputStream(InputStream in, boolean detectBinary) {
		this(in, detectBinary, false);
	}

	/**
	 * Creates a new InputStream, wrapping the specified stream
	 *
	 * @param in
	 *            raw input stream
	 * @param detectBinary
	 *            whether binaries should be detected
	 * @param abortIfBinary
	 *            throw an IOException if the file is binary
	 * @since 3.3
	 */
	public AutoLFInputStream(InputStream in, boolean detectBinary,
			boolean abortIfBinary) {
		this.in = in;
		this.detectBinary = detectBinary;
		this.abortIfBinary = abortIfBinary;
	}

	/** {@inheritDoc} */
	@Override
	public int read() throws IOException {
		final int read = read(single, 0, 1);
		return read == 1 ? single[0] & 0xff : -1;
	}

	/** {@inheritDoc} */
	@Override
	public int read(byte[] bs, int off, int len)
			throws IOException {
		if (len == 0)
			return 0;

		if (cnt == -1)
			return -1;

		int i = off;
		final int end = off + len;

		while (i < end) {
			if (ptr == cnt && !fillBuffer()) {
				break;
			}

			byte b = buf[ptr++];
			if (isBinary || b != '\r') {
				// Logic for binary files ends here
				bs[i++] = b;
				continue;
			}

			if (ptr == cnt && !fillBuffer()) {
				bs[i++] = '\r';
				break;
			}

			if (buf[ptr] == '\n') {
				bs[i++] = '\n';
				ptr++;
			} else
				bs[i++] = '\r';
		}

		return i == off ? -1 : i - off;
	}

	/**
	 * Whether the stream has detected as a binary so far.
	 *
	 * @return true if the stream has detected as a binary so far.
	 * @since 3.3
	 */
	public boolean isBinary() {
		return isBinary;
	}

	/** {@inheritDoc} */
	@Override
	public void close() throws IOException {
		in.close();
	}

	private boolean fillBuffer() throws IOException {
		cnt = 0;
		while (cnt < buf.length) {
			int n = in.read(buf, cnt, buf.length - cnt);
			if (n < 0) {
				break;
			}
			cnt += n;
		}
		if (cnt < 1) {
			cnt = -1;
			return false;
		}
		if (detectBinary) {
			isBinary = RawText.isBinary(buf, cnt);
			detectBinary = false;
			if (isBinary && abortIfBinary)
				throw new IsBinaryException();
		}
		ptr = 0;
		return true;
	}
}
