/*
 * 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.api;

import static org.junit.Assert.assertArrayEquals;
import static org.eclipse.jgit.lib.CoreConfig.EolStreamType.*;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

import org.eclipse.jgit.lib.CoreConfig.EolStreamType;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.io.EolStreamTypeUtil;
import org.junit.Test;

/**
 * Unit tests for end-of-line conversion streams
 */
public class EolStreamTypeUtilTest {

	@Test
	public void testCheckoutDirect() throws Exception {
		testCheckout(DIRECT, DIRECT, "", "");
		testCheckout(DIRECT, DIRECT, "\r", "\r");
		testCheckout(DIRECT, DIRECT, "\n", "\n");

		testCheckout(DIRECT, DIRECT, "\r\n", "\r\n");
		testCheckout(DIRECT, DIRECT, "\n\r", "\n\r");

		testCheckout(DIRECT, DIRECT, "\n\r\n", "\n\r\n");
		testCheckout(DIRECT, DIRECT, "\r\n\r", "\r\n\r");

		testCheckout(DIRECT, DIRECT, "a\nb\n", "a\nb\n");
		testCheckout(DIRECT, DIRECT, "a\rb\r", "a\rb\r");
		testCheckout(DIRECT, DIRECT, "a\n\rb\n\r", "a\n\rb\n\r");
		testCheckout(DIRECT, DIRECT, "a\r\nb\r\n", "a\r\nb\r\n");
	}

	@Test
	public void testCheckoutLF() throws Exception {
		testCheckout(TEXT_LF, AUTO_LF, "", "");
		testCheckout(TEXT_LF, AUTO_LF, "\r", "\r");
		testCheckout(TEXT_LF, AUTO_LF, "\n", "\n");

		testCheckout(TEXT_LF, AUTO_LF, "\r\n", "\n");
		testCheckout(TEXT_LF, AUTO_LF, "\n\r", "\n\r");

		testCheckout(TEXT_LF, AUTO_LF, "\n\r\n", "\n\n");
		testCheckout(TEXT_LF, AUTO_LF, "\r\n\r", "\n\r");

		testCheckout(TEXT_LF, AUTO_LF, "a\nb\n", "a\nb\n");
		testCheckout(TEXT_LF, AUTO_LF, "a\rb\r", "a\rb\r");
		testCheckout(TEXT_LF, AUTO_LF, "a\n\rb\n\r", "a\n\rb\n\r");
		testCheckout(TEXT_LF, AUTO_LF, "a\r\nb\r\n", "a\nb\n");
	}

	@Test
	public void testCheckoutCRLF() throws Exception {
		testCheckout(TEXT_CRLF, AUTO_CRLF, "", "");
		testCheckout(TEXT_CRLF, AUTO_CRLF, "\r", "\r");
		testCheckout(TEXT_CRLF, AUTO_CRLF, "\n", "\r\n");

		testCheckout(TEXT_CRLF, AUTO_CRLF, "\r\n", "\r\n");
		testCheckout(TEXT_CRLF, AUTO_CRLF, "\n\r", "\r\n\r");

		testCheckout(TEXT_CRLF, AUTO_CRLF, "\n\r\n", "\r\n\r\n");
		testCheckout(TEXT_CRLF, AUTO_CRLF, "\r\n\r", "\r\n\r");

		testCheckout(TEXT_CRLF, AUTO_CRLF, "a\nb\n", "a\r\nb\r\n");
		testCheckout(TEXT_CRLF, AUTO_CRLF, "a\rb\r", "a\rb\r");
		testCheckout(TEXT_CRLF, AUTO_CRLF, "a\n\rb\n\r", "a\r\n\rb\r\n\r");
		testCheckout(TEXT_CRLF, AUTO_CRLF, "a\r\nb\r\n", "a\r\nb\r\n");
	}

	/**
	 * Test stream type detection based on stream content.
	 * <p>
	 * Tests three things with the output text:
	 * <p>
	 * 1) conversion if output was declared as text
	 * <p>
	 * 2) conversion if output was declared as potentially text (AUTO_...) and
	 * is in fact text
	 * <p>
	 * 3) conversion if modified output (now with binary characters) was
	 * declared as potentially text but now contains binary characters
	 * <p>
	 *
	 * @param streamTypeText
	 *            is the enum meaning that the output is definitely text (no
	 *            binary check at all)
	 * @param streamTypeWithBinaryCheck
	 *            is the enum meaning that the output may be text (binary check
	 *            is done)
	 * @param output
	 *            is a text output without binary characters
	 * @param expectedConversion
	 *            is the expected converted output without binary characters
	 * @throws Exception
	 */
	private void testCheckout(EolStreamType streamTypeText,
			EolStreamType streamTypeWithBinaryCheck, String output,
			String expectedConversion) throws Exception {
		ByteArrayOutputStream b;
		byte[] outputBytes = output.getBytes(StandardCharsets.UTF_8);
		byte[] expectedConversionBytes = expectedConversion
				.getBytes(StandardCharsets.UTF_8);

		// test using output text and assuming it was declared TEXT
		b = new ByteArrayOutputStream();
		try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
				streamTypeText)) {
			out.write(outputBytes);
		}
		assertArrayEquals(expectedConversionBytes, b.toByteArray());

		// test using ouput text and assuming it was declared AUTO, using binary
		// detection
		b = new ByteArrayOutputStream();
		try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
				streamTypeWithBinaryCheck)) {
			out.write(outputBytes);
		}
		assertArrayEquals(expectedConversionBytes, b.toByteArray());

		// now pollute output text with some binary bytes
		outputBytes = extendWithBinaryData(outputBytes);
		expectedConversionBytes = extendWithBinaryData(expectedConversionBytes);

		// again, test using output text and assuming it was declared TEXT
		b = new ByteArrayOutputStream();
		try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
				streamTypeText)) {
			out.write(outputBytes);
		}
		assertArrayEquals(expectedConversionBytes, b.toByteArray());

		// again, test using ouput text and assuming it was declared AUTO, using
		// binary
		// detection
		b = new ByteArrayOutputStream();
		try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
				streamTypeWithBinaryCheck)) {
			out.write(outputBytes);
		}
		// expect no conversion
		assertArrayEquals(outputBytes, b.toByteArray());
	}

	@Test
	public void testCheckinDirect() throws Exception {
		testCheckin(DIRECT, DIRECT, "", "");
		testCheckin(DIRECT, DIRECT, "\r", "\r");
		testCheckin(DIRECT, DIRECT, "\n", "\n");

		testCheckin(DIRECT, DIRECT, "\r\n", "\r\n");
		testCheckin(DIRECT, DIRECT, "\n\r", "\n\r");

		testCheckin(DIRECT, DIRECT, "\n\r\n", "\n\r\n");
		testCheckin(DIRECT, DIRECT, "\r\n\r", "\r\n\r");

		testCheckin(DIRECT, DIRECT, "a\nb\n", "a\nb\n");
		testCheckin(DIRECT, DIRECT, "a\rb\r", "a\rb\r");
		testCheckin(DIRECT, DIRECT, "a\n\rb\n\r", "a\n\rb\n\r");
		testCheckin(DIRECT, DIRECT, "a\r\nb\r\n", "a\r\nb\r\n");
	}

	@Test
	public void testCheckinLF() throws Exception {
		testCheckin(TEXT_LF, AUTO_LF, "", "");
		testCheckin(TEXT_LF, AUTO_LF, "\r", "\r");
		testCheckin(TEXT_LF, AUTO_LF, "\n", "\n");

		testCheckin(TEXT_LF, AUTO_LF, "\r\n", "\n");
		testCheckin(TEXT_LF, AUTO_LF, "\n\r", "\n\r");

		testCheckin(TEXT_LF, AUTO_LF, "\n\r\n", "\n\n");
		testCheckin(TEXT_LF, AUTO_LF, "\r\n\r", "\n\r");

		testCheckin(TEXT_LF, AUTO_LF, "a\nb\n", "a\nb\n");
		testCheckin(TEXT_LF, AUTO_LF, "a\rb\r", "a\rb\r");
		testCheckin(TEXT_LF, AUTO_LF, "a\n\rb\n\r", "a\n\rb\n\r");
		testCheckin(TEXT_LF, AUTO_LF, "a\r\nb\r\n", "a\nb\n");
	}

	@Test
	public void testCheckinCRLF() throws Exception {
		testCheckin(TEXT_CRLF, AUTO_CRLF, "", "");
		testCheckin(TEXT_CRLF, AUTO_CRLF, "\r", "\r");
		testCheckin(TEXT_CRLF, AUTO_CRLF, "\n", "\r\n");

		testCheckin(TEXT_CRLF, AUTO_CRLF, "\r\n", "\r\n");
		testCheckin(TEXT_CRLF, AUTO_CRLF, "\n\r", "\r\n\r");

		testCheckin(TEXT_CRLF, AUTO_CRLF, "\n\r\n", "\r\n\r\n");
		testCheckin(TEXT_CRLF, AUTO_CRLF, "\r\n\r", "\r\n\r");

		testCheckin(TEXT_CRLF, AUTO_CRLF, "a\nb\n", "a\r\nb\r\n");
		testCheckin(TEXT_CRLF, AUTO_CRLF, "a\rb\r", "a\rb\r");
		testCheckin(TEXT_CRLF, AUTO_CRLF, "a\n\rb\n\r", "a\r\n\rb\r\n\r");
		testCheckin(TEXT_CRLF, AUTO_CRLF, "a\r\nb\r\n", "a\r\nb\r\n");
	}

	/**
	 * Test stream type detection based on stream content.
	 * <p>
	 * Tests three things with the input text:
	 * <p>
	 * 1) conversion if input was declared as text
	 * <p>
	 * 2) conversion if input was declared as potentially text (AUTO_...) and is
	 * in fact text
	 * <p>
	 * 3) conversion if modified input (now with binary characters) was declared
	 * as potentially text but now contains binary characters
	 * <p>
	 *
	 * @param streamTypeText
	 *            is the enum meaning that the input is definitely text (no
	 *            binary check at all)
	 * @param streamTypeWithBinaryCheck
	 *            is the enum meaning that the input may be text (binary check
	 *            is done)
	 * @param input
	 *            is a text input without binary characters
	 * @param expectedConversion
	 *            is the expected converted input without binary characters
	 * @throws Exception
	 */
	private void testCheckin(EolStreamType streamTypeText,
			EolStreamType streamTypeWithBinaryCheck, String input,
			String expectedConversion) throws Exception {
		byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8);
		byte[] expectedConversionBytes = expectedConversion
				.getBytes(StandardCharsets.UTF_8);

		// test using input text and assuming it was declared TEXT
		try (InputStream in = EolStreamTypeUtil.wrapInputStream(
				new ByteArrayInputStream(inputBytes),
				streamTypeText)) {
			byte[] b = new byte[1024];
			int len = IO.readFully(in, b, 0);
			assertArrayEquals(expectedConversionBytes, Arrays.copyOf(b, len));
		}

		// test using input text and assuming it was declared AUTO, using binary
		// detection
		try (InputStream in = EolStreamTypeUtil.wrapInputStream(
				new ByteArrayInputStream(inputBytes),
				streamTypeWithBinaryCheck)) {
			byte[] b = new byte[1024];
			int len = IO.readFully(in, b, 0);
			assertArrayEquals(expectedConversionBytes, Arrays.copyOf(b, len));
		}

		// now pollute input text with some binary bytes
		inputBytes = extendWithBinaryData(inputBytes);
		expectedConversionBytes = extendWithBinaryData(expectedConversionBytes);

		// again, test using input text and assuming it was declared TEXT
		try (InputStream in = EolStreamTypeUtil.wrapInputStream(
				new ByteArrayInputStream(inputBytes), streamTypeText)) {
			byte[] b = new byte[1024];
			int len = IO.readFully(in, b, 0);
			assertArrayEquals(expectedConversionBytes, Arrays.copyOf(b, len));
		}

		// again, test using input text and assuming it was declared AUTO, using
		// binary
		// detection
		try (InputStream in = EolStreamTypeUtil.wrapInputStream(
				new ByteArrayInputStream(inputBytes),
				streamTypeWithBinaryCheck)) {
			byte[] b = new byte[1024];
			int len = IO.readFully(in, b, 0);
			// expect no conversion
			assertArrayEquals(inputBytes, Arrays.copyOf(b, len));
		}
	}

	private byte[] extendWithBinaryData(byte[] data) throws Exception {
		int n = 3;
		byte[] dataEx = new byte[data.length + n];
		System.arraycopy(data, 0, dataEx, 0, data.length);
		for (int i = 0; i < n; i++) {
			dataEx[data.length + i] = (byte) i;
		}
		return dataEx;
	}

}
