/*******************************************************************************
 * Copyright (c) 2020 Paul Pazderski and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Paul Pazderski - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.tests.console;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import org.eclipse.debug.core.IBinaryStreamListener;
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.model.IBinaryStreamMonitor;
import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.debug.internal.core.OutputStreamMonitor;
import org.eclipse.debug.tests.AbstractDebugTest;
import org.eclipse.debug.tests.TestUtil;
import org.junit.Before;
import org.junit.Test;

/**
 * Tests the {@link OutputStreamMonitor}.
 */
public class OutputStreamMonitorTests extends AbstractDebugTest {

	/** Stream to simulate an application writing to system out. */
	PipedOutputStream sysout = new PipedOutputStream();
	/** The {@link OutputStreamMonitor} used for the test runs. */
	TestOutputStreamMonitor monitor;
	/** The bytes received through listener. */
	ByteArrayOutputStream notifiedBytes = new ByteArrayOutputStream();
	/** The strings received through listener. */
	StringBuilder notifiedChars = new StringBuilder();

	IBinaryStreamListener fBinaryListener = new IBinaryStreamListener() {
		@Override
		public void streamAppended(byte[] data, IBinaryStreamMonitor mon) {
			if (monitor == mon) {
				try {
					notifiedBytes.write(data);
				} catch (IOException e) {
				}
			}
		}
	};
	IStreamListener fStreamListener = new IStreamListener() {
		@Override
		public void streamAppended(String text, IStreamMonitor mon) {
			if (monitor == mon) {
				notifiedChars.append(text);
			}
		}
	};

	@Override
	@Before
	@SuppressWarnings("resource")
	public void setUp() throws IOException {
		monitor = new TestOutputStreamMonitor(new PipedInputStream(sysout), null);
	}

	/**
	 * Simple test for output stream monitor. Test buffering and listeners.
	 */
	@Test
	public void testBufferedOutputStreamMonitor() throws Exception {
		String input = "o\u00F6O";
		byte[] byteInput = input.getBytes(StandardCharsets.UTF_8);
		try {
			monitor.addBinaryListener(fBinaryListener);
			monitor.addListener(fStreamListener);

			sysout.write(byteInput, 0, 2);
			sysout.flush();
			monitor.startMonitoring();
			TestUtil.waitWhile(() -> notifiedBytes.size() < 2, 1000);
			String contents = monitor.getContents();
			assertEquals("Monitor read wrong content.", input.substring(0, 1), contents);
			assertEquals("Notified and buffered content differ.", contents, notifiedChars.toString());
			assertEquals("Failed to access buffered content twice.", contents, monitor.getContents());
			byte[] data = monitor.getData();
			byte[] expected = new byte[2];
			System.arraycopy(byteInput, 0, expected, 0, 2);
			assertArrayEquals("Monitor read wrong binary content.", expected, data);
			assertArrayEquals("Notified and buffered binary content differ.", data, notifiedBytes.toByteArray());
			assertArrayEquals("Failed to access buffered binary content twice.", data, monitor.getData());

			monitor.flushContents();
			sysout.write(byteInput, 2, byteInput.length - 2);
			sysout.flush();
			TestUtil.waitWhile(() -> notifiedBytes.size() < byteInput.length, 1000);
			contents = monitor.getContents();
			assertEquals("Monitor buffered wrong content.", input.substring(1), contents);
			assertEquals("Failed to access buffered content twice.", contents, monitor.getContents());
			assertEquals("Wrong content through listener.", input, notifiedChars.toString());
			data = monitor.getData();
			expected = new byte[byteInput.length - 2];
			System.arraycopy(byteInput, 2, expected, 0, expected.length);
			assertArrayEquals("Monitor read wrong binary content.", expected, data);
			assertArrayEquals("Failed to access buffered binary content twice.", data, monitor.getData());
			assertArrayEquals("Wrong binary content through listener.", byteInput, notifiedBytes.toByteArray());
		} finally {
			sysout.close();
			monitor.close();
		}
	}

	/**
	 * Simple test for output stream monitor. Test listeners without buffering.
	 */
	@Test
	public void testUnbufferedOutputStreamMonitor() throws Exception {
		String input = "o\u00F6O";
		byte[] byteInput = input.getBytes(StandardCharsets.UTF_8);
		try {
			monitor.addBinaryListener(fBinaryListener);
			monitor.addListener(fStreamListener);

			sysout.write(byteInput, 0, 2);
			sysout.flush();
			monitor.setBuffered(false);
			monitor.startMonitoring();
			TestUtil.waitWhile(() -> notifiedBytes.size() < 2, 1000);
			assertEquals("Monitor read wrong content.", input.substring(0, 1), notifiedChars.toString());
			byte[] expected = new byte[2];
			System.arraycopy(byteInput, 0, expected, 0, 2);
			assertArrayEquals("Monitor read wrong binary content.", expected, notifiedBytes.toByteArray());

			monitor.flushContents();
			sysout.write(byteInput, 2, byteInput.length - 2);
			sysout.flush();
			TestUtil.waitWhile(() -> notifiedBytes.size() < byteInput.length, 1000);
			assertEquals("Wrong content through listener.", input, notifiedChars.toString());
			expected = new byte[byteInput.length - 2];
			System.arraycopy(byteInput, 2, expected, 0, expected.length);
			assertArrayEquals("Wrong binary content through listener.", byteInput, notifiedBytes.toByteArray());
		} finally {
			sysout.close();
			monitor.close();
		}
	}

	/**
	 * Test that passing <code>null</code> as charset does not raise exceptions.
	 */
	@Test
	public void testNullCharset() throws Exception {
		String input = "o\u00F6O\u00EFiI\u00D6\u00D8\u00F8";

		monitor.addListener(fStreamListener);
		monitor.startMonitoring();
		try (PrintStream out = new PrintStream(sysout)) {
			out.print(input);
		}
		sysout.flush();

		TestUtil.waitWhile(() -> notifiedChars.length() < input.length(), 500);
		assertEquals("Monitor read wrong content.", input, notifiedChars.toString());
	}

	/**
	 * {@link OutputStreamMonitor} with public {@link #startMonitoring()} for
	 * testing.
	 */
	private static class TestOutputStreamMonitor extends OutputStreamMonitor {

		public TestOutputStreamMonitor(InputStream stream, Charset charset) {
			super(stream, charset);
		}

		@Override
		public void startMonitoring() {
			super.startMonitoring();
		}

		@Override
		public void close() {
			super.close();
		}
	}
}
