/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.debug.tests.core;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;

import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.debug.tests.TestUtil;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.TextConsole;
import org.eclipse.ui.internal.console.IOConsolePartitioner;

/**
 * Tests console lifecycle and output handling.
 */
public class ConsoleTests extends AbstractDebugTest {

	public ConsoleTests(String name) {
		super(name);
	}

	class TestConsole extends MessageConsole {

	    public boolean fInit = false;
	    public boolean fDispose = false;

        public TestConsole(boolean autoLifecycle) {
            super("Life's like that", null, autoLifecycle);
        }

        @Override
		protected void init() {
            super.init();
            fInit = true;
        }

        @Override
		protected void dispose() {
            super.dispose();
            fDispose = true;
        }

	}

	/**
	 * Test that when a process is removed from a launch, the associated
	 * console is closed.
	 *
	 * @throws Exception
	 */
	public void testRemoveProcess() throws Exception {
		String typeName = "Breakpoints";
		IJavaDebugTarget target = null;
		try {
			final IJavaDebugTarget otherTarget = launchAndTerminate(typeName);
			target = otherTarget;
			IProcess process = target.getProcess();
			assertNotNull("Missing VM process", process);
			ILaunch launch = target.getLaunch();
			// make sure the console exists
			DebugUIPlugin.getStandardDisplay().syncExec(new Runnable() {
				@Override
				public void run() {
					IConsole console = DebugUITools.getConsole(otherTarget);
					assertNotNull("Missing console", console);
				}
			});
			launch.removeProcess(process);
			// make sure the console is gone
			DebugUIPlugin.getStandardDisplay().syncExec(new Runnable() {
				@Override
				public void run() {
					IConsole console = DebugUITools.getConsole(otherTarget);
					assertNull("Console should no longer exist", console);
				}
			});
		} finally {
			terminateAndRemove(target);
		}
	}

	public void testAutoLifecycle() {
	    TestConsole console = new TestConsole(true);
	    IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
	    consoleManager.addConsoles(new IConsole[]{console});
	    consoleManager.removeConsoles(new IConsole[]{console});
	    assertTrue("Console was not initialized", console.fInit);
	    assertTrue("Console was not disposed", console.fDispose);
	}

	public void testManualLifecycle() {
	    TestConsole console = new TestConsole(false);
	    IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
	    consoleManager.addConsoles(new IConsole[]{console});
	    consoleManager.removeConsoles(new IConsole[]{console});
	    assertTrue("Console was initialized", !console.fInit);
	    assertTrue("Console was disposed", !console.fDispose);
	    console.dispose();
	}

	/**
	 * Test synchronization of standard and error output stream of started process.
	 * <p>
	 * This variant tests output on multiple lines and is launched in DEBUG mode.
	 * </p>
	 *
	 * @throws Exception
	 *             if test failed
	 */
	public void testConsoleOutputSynchronization() throws Exception {
		String typeName = "OutSync";
		IJavaDebugTarget target = null;
		try {
			ILaunchConfiguration launchConfig = getLaunchConfiguration(typeName);
			ILaunchConfigurationWorkingCopy launchCopy = launchConfig.getWorkingCopy();
			launchCopy.setAttribute(DebugPlugin.ATTR_MERGE_OUTPUT, true);
			target = launchAndTerminate(launchCopy, DEFAULT_TIMEOUT);
			String content = getConsoleContent(target.getProcess());
			// normalize new lines to unix style
			content = content.replace("\r\n", "\n").replace('\r', '\n');
			String expectedOutput = String.join("", Collections.nCopies(content.length() / 4, "o\ne\n"));
			assertEquals("Received wrong output. Probably not synchronized.", expectedOutput, content);
		} finally {
			if (target != null) {
				terminateAndRemove(target);
			}
		}
	}

	/**
	 * Test synchronization of standard and error output stream of started process.
	 * <p>
	 * This variant tests output on single line and is launched in RUN mode.
	 * </p>
	 *
	 * @throws Exception
	 *             if test failed
	 */
	public void testConsoleOutputSynchronization2() throws Exception {
		String typeName = "OutSync2";
		ILaunch launch = null;
		try {
			ILaunchConfiguration launchConfig = getLaunchConfiguration(typeName);
			ILaunchConfigurationWorkingCopy launchCopy = launchConfig.getWorkingCopy();
			launchCopy.setAttribute(DebugPlugin.ATTR_MERGE_OUTPUT, true);
			launch = launchCopy.launch(ILaunchManager.RUN_MODE, null);
			TestUtil.waitForJobs(getName(), 0, DEFAULT_TIMEOUT);
			String content = getConsoleContent(launch.getProcesses()[0]);
			String expectedOutput = String.join("", Collections.nCopies(content.length() / 2, "oe"));
			assertEquals("Received wrong output. Probably not synchronized.", expectedOutput, content);
		} finally {
			if (launch != null) {
				getLaunchManager().removeLaunch(launch);
			}
		}
	}

	/**
	 * Test if process error output has another color in console than standard output.
	 *
	 * @throws Exception
	 *             if test failed
	 */
	public void testConsoleErrorColoring() throws Exception {
		String typeName = "OutSync";
		IJavaDebugTarget target = null;
		try {
			target = launchAndTerminate(typeName);
			final IProcess process = target.getProcess();
			assertNotNull("Missing VM process.", process);
			final IConsole console = DebugUITools.getConsole(process);
			assertTrue("Console is not a TextConsole.", console instanceof TextConsole);
			final TextConsole textConsole = (TextConsole) console;
			final IDocumentPartitioner partitioner = textConsole.getDocument().getDocumentPartitioner();
			assertTrue("Partitioner is not a IOConsolePartitioner.", partitioner instanceof IOConsolePartitioner);
			final IOConsolePartitioner ioPartitioner = (IOConsolePartitioner) partitioner;
			TestUtil.waitForJobs(getName(), 100, DEFAULT_TIMEOUT); // wait for output appending

			final long numStyleTypes = Arrays.stream(ioPartitioner.getStyleRanges(0, textConsole.getDocument().getLength())).map((s) -> s.foreground).distinct().count();
			assertTrue("Console partitioner did not distinct standard and error output.", numStyleTypes > 1);
		} finally {
			if (target != null) {
				terminateAndRemove(target);
			}
		}
	}

	/**
	 * Try to get the console content associated with given process.
	 *
	 * @param process
	 *            the process on whose output we are interested
	 * @return the raw content in console probably written by given process. Note: result may be affected by user input and console trimming.
	 * @throws Exception
	 *             if content retrieval failed
	 */
	private String getConsoleContent(IProcess process) throws Exception {
		assertNotNull("Missing VM process.", process);
		final IConsole console = DebugUITools.getConsole(process);
		assertNotNull("Missing console", console);
		assertTrue("Console is not a TextConsole.", console instanceof TextConsole);
		final TextConsole textConsole = (TextConsole) console;
		TestUtil.waitForJobs(getName(), 100, DEFAULT_TIMEOUT); // wait for output appending
		assertEquals("Test program failed with error.", 0, process.getExitValue());
		final IDocument consoleDocument = textConsole.getDocument();
		return consoleDocument.get();
	}
	/**
	 * Test console receiving UTF-8 output from process where two-byte UTF-8 characters start at even offsets.
	 *
	 * @throws Exception
	 *             if the test gets in trouble
	 */
	public void testBug545769_UTF8OutEven() throws Exception {
		// 4200 umlaute results in 8400 byte of output which should be more than most common buffer sizes.
		utf8OutputTest(0, 4200, 5);
	}

	/**
	 * Test console receiving UTF-8 output from process where two-byte UTF-8 characters start at odd offsets.
	 *
	 * @throws Exception
	 *             if the test gets in trouble
	 */
	public void testBug545769_UTF8OutOdd() throws Exception {
		// 4200 umlaute results in 8400 byte of output which should be more than most common buffer sizes.
		utf8OutputTest(1, 4200, 5);
	}

	/**
	 * Shared test code for possible UTF-8 process output corruption.
	 *
	 * @param numAscii
	 *            number of one byte UTF-8 characters the process prints first
	 * @param numUmlaut
	 *            number of two byte UTF-8 character the process prints second
	 * @param repetitions
	 *            number of output repetitions. This test requires the process can write its output faster than the console can read it.
	 * @throws Exception
	 *             if the test gets in trouble
	 */
	private void utf8OutputTest(int numAscii, int numUmlaut, int repetitions) throws Exception {
		final String typeName = "ConsoleOutputUmlaut";

		final IPreferenceStore debugPrefStore = DebugUIPlugin.getDefault().getPreferenceStore();
		debugPrefStore.setValue(IDebugPreferenceConstants.CONSOLE_LIMIT_CONSOLE_OUTPUT, false);
		debugPrefStore.setValue(IDebugPreferenceConstants.CONSOLE_WRAP, true);
		debugPrefStore.setValue(IDebugPreferenceConstants.CONSOLE_WIDTH, 100);

		final ILaunchConfiguration launchConfig = getLaunchConfiguration(typeName);
		final ILaunchConfigurationWorkingCopy launchCopy = launchConfig.getWorkingCopy();
		String arg = String.join(" ", Integer.toString(numAscii), Integer.toString(numUmlaut), Integer.toString(repetitions));
		launchCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, arg);
		launchCopy.setAttribute(DebugPlugin.ATTR_CONSOLE_ENCODING, StandardCharsets.UTF_8.name());

		ILaunch launch = null;
		try {
			launch = launchCopy.launch(ILaunchManager.RUN_MODE, null);
			final IProcess process = launch.getProcesses()[0];
			assertNotNull("Missing VM process", process);
			TestUtil.waitForJobs(getName(), 25, DEFAULT_TIMEOUT); // wait for console creation
			final IConsole console = DebugUITools.getConsole(process);
			assertNotNull("Missing console", console);
			assertTrue("Console is not a TextConsole", console instanceof TextConsole);
			final TextConsole textConsole = (TextConsole) console;
			TestUtil.waitForJobs(getName(), 100, DEFAULT_TIMEOUT); // wait for output appending
			assertEquals("Test program failed with error.", 0, process.getExitValue());
			final IDocument consoleDocument = textConsole.getDocument();
			final int expectedLength = (numAscii + numUmlaut + 2) * repetitions;
			if (consoleDocument.getLength() > expectedLength) {
				// debug code for test failures
				int offset = expectedLength - 20;
				String trail = consoleDocument.get(offset, consoleDocument.getLength() - offset);
				System.out.println(trail);
			}
			assertEquals("Wrong number of characters in console.", expectedLength, consoleDocument.getLength());
		} finally {
			debugPrefStore.setValue(IDebugPreferenceConstants.CONSOLE_LIMIT_CONSOLE_OUTPUT, true);
			debugPrefStore.setValue(IDebugPreferenceConstants.CONSOLE_WRAP, false);
			if (launch != null) {
				if (launch.getProcesses() != null) {
					for (IProcess process : launch.getProcesses()) {
						process.terminate();
					}
				}
				getLaunchManager().removeLaunch(launch);
			}
		}
	}
}
