/*
 * Copyright (C) 2015, Ivan Motsch <ivan.motsch@bsiag.com>
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.eclipse.jgit.util.io;

import java.io.IOException;
import java.io.OutputStream;

import org.eclipse.jgit.diff.RawText;

/**
 * An OutputStream that reduces CRLF to LF.
 *
 * Existing single CR are not changed to LF, but retained as is.
 *
 * A binary check on the first 8000 bytes is performed and in case of binary
 * files, canonicalization is turned off (for the complete file).
 *
 * @since 4.3
 */
public class AutoLFOutputStream extends OutputStream {

	static final int BUFFER_SIZE = 8000;

	private final OutputStream out;

	private int buf = -1;

	private byte[] binbuf = new byte[BUFFER_SIZE];

	private byte[] onebytebuf = new byte[1];

	private int binbufcnt = 0;

	private boolean detectBinary;

	private boolean isBinary;

	/**
	 * @param out
	 */
	public AutoLFOutputStream(OutputStream out) {
		this(out, true);
	}

	/**
	 * @param out
	 * @param detectBinary
	 *            whether binaries should be detected
	 */
	public AutoLFOutputStream(OutputStream out, boolean detectBinary) {
		this.out = out;
		this.detectBinary = detectBinary;
	}

	@Override
	public void write(int b) throws IOException {
		onebytebuf[0] = (byte) b;
		write(onebytebuf, 0, 1);
	}

	@Override
	public void write(byte[] b) throws IOException {
		int overflow = buffer(b, 0, b.length);
		if (overflow > 0) {
			write(b, b.length - overflow, overflow);
		}
	}

	@Override
	public void write(byte[] b, final int startOff, final int startLen)
			throws IOException {
		final int overflow = buffer(b, startOff, startLen);
		if (overflow < 0) {
			return;
		}
		final int off = startOff + startLen - overflow;
		final int len = overflow;
		if (len == 0) {
			return;
		}
		int lastw = off;
		if (isBinary) {
			out.write(b, off, len);
			return;
		}
		for (int i = off; i < off + len; ++i) {
			final byte c = b[i];
			if (c == '\r') {
				// skip write r but backlog r
				if (lastw < i) {
					out.write(b, lastw, i - lastw);
				}
				lastw = i + 1;
				buf = '\r';
			} else if (c == '\n') {
				if (buf == '\r') {
					out.write('\n');
					lastw = i + 1;
					buf = -1;
				} else {
					if (lastw < i + 1) {
						out.write(b, lastw, i + 1 - lastw);
					}
					lastw = i + 1;
				}
			} else {
				if (buf == '\r') {
					out.write('\r');
					lastw = i;
				}
				buf = -1;
			}
		}
		if (lastw < off + len) {
			out.write(b, lastw, off + len - lastw);
		}
	}

	private int buffer(byte[] b, int off, int len) throws IOException {
		if (binbufcnt > binbuf.length) {
			return len;
		}
		int copy = Math.min(binbuf.length - binbufcnt, len);
		System.arraycopy(b, off, binbuf, binbufcnt, copy);
		binbufcnt += copy;
		int remaining = len - copy;
		if (remaining > 0) {
			decideMode();
		}
		return remaining;
	}

	private void decideMode() throws IOException {
		if (detectBinary) {
			isBinary = RawText.isBinary(binbuf, binbufcnt);
			detectBinary = false;
		}
		int cachedLen = binbufcnt;
		binbufcnt = binbuf.length + 1; // full!
		write(binbuf, 0, cachedLen);
	}

	@Override
	public void flush() throws IOException {
		if (binbufcnt <= binbuf.length) {
			decideMode();
		}
		out.flush();
	}

	@Override
	public void close() throws IOException {
		flush();
		if (buf == '\r') {
			out.write(buf);
			buf = -1;
		}
		out.close();
	}
}
