/*******************************************************************************
 *  Copyright (c) 2000, 2015 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 static java.util.stream.Collectors.joining;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.ui.console.IConsole;
import org.eclipse.debug.ui.console.IConsoleLineTrackerExtension;
import org.eclipse.jdt.debug.testplugin.ConsoleLineTracker;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;

/**
 * Tests for program and VM arguments
 */
public class ArgumentTests extends AbstractDebugTest {

    private Object fLock = new Object();
	protected boolean fUseArgfile = false;

	private class ConsoleArgumentOutputRetriever implements IConsoleLineTrackerExtension {

		StringBuilder buffer;
		IDocument document;
		boolean closed = false;

		/**
		 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#dispose()
		 */
		@Override
		public void dispose() {}

		/**
		 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#init(org.eclipse.debug.ui.console.IConsole)
		 */
		@Override
		public void init(IConsole console) {
			buffer = new StringBuilder();
			document = console.getDocument();
		}

		/**
		 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#lineAppended(org.eclipse.jface.text.IRegion)
		 */
		@Override
		public void lineAppended(IRegion line) {
			try {
                assertNotNull("received notification of invalid line", line);
                assertNotNull("buffer is null", buffer);
                String text = document.get(line.getOffset(), line.getLength());
				if (!JavaOutputHelpers.isKnownExtraneousOutput(text)) {
					buffer.append(text);
				}
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
		}

		/**
		 * @see org.eclipse.debug.ui.console.IConsoleLineTrackerExtension#consoleClosed()
		 */
		@Override
		public void consoleClosed() {
			synchronized (fLock) {
				closed = true;
			    fLock.notifyAll();
            }
		}

		/**
		 * @return the output
		 */
		public String getOutput() {
			// wait to be closed
		    synchronized (fLock) {
		    	if (!closed) {
			        try {
	                    fLock.wait(DEFAULT_TIMEOUT);
	                } catch (InterruptedException e) {
	                }
		    	}
		    }
		    if (!closed) {
				// output contents to console in case of error
				if (buffer != null) {
				    System.out.println();
				    System.out.println(ArgumentTests.this.getName());
				    System.out.println("\treceived " + buffer.length() + " chars: " + buffer.toString());
				}
		    }
		    assertNotNull("Line tracker did not receive init notification", buffer);
		    assertTrue("Line tracker did not receive close notification", closed);
			return buffer.toString();
		}

}

	/**
	 * Constructor
	 * @param name the name of the test
	 */
	public ArgumentTests(String name) {
		super(name);
	}

	/**
	 * Creates and returns a new launch config the given name
	 */
	protected ILaunchConfigurationWorkingCopy newConfiguration(IContainer container, String name) throws CoreException {
		ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		return type.newInstance(container, name);
	}

	/*
	 * VM argument tests
	 */
	/**
	 * Test a single VM argument.
	 * Program output should be: foo
	 * @throws CoreException
	 */
	public void testVMArgSingle() throws CoreException {
		testWithVMArg("-Dfoo=foo", "foo");
	}
	/**
	 * Test a VM argument with quotes in a valid location.
	 * Program output should be: foo
	 * @throws CoreException
	 */
	public void testVMArgSimpleQuotes() throws CoreException {
		testWithVMArg("-Dfoo=\"foo\"", "foo");
	}
	/**
	 * Test a VM argument with the standard style quoting for arguments with
	 * spaces.
	 * Program output should be: foo bar
	 * @throws CoreException
	 */
	public void testVMArgStandardQuotes() throws CoreException {
		testWithVMArg("-Dfoo=\"foo bar\"", "foo bar");
	}
	/**
	 * Test a VM argument with quotes in a standard location.
	 * Program output should be: "foo"
	 * @throws CoreException
	 */
	public void testVMArgStandardEmbeddedQuotes() throws CoreException {
		testWithVMArg("-Dfoo=\"\\\"foo\\\"\"", "\"foo\"");
	}
	/**
	 * Test a VM argument with the quoting style we recommended as a workaround
	 * to a bug (now fixed) that we suggested in the past.
	 * Program output should be: foo bar
	 * @throws CoreException
	 */
	public void testVMArgWorkaroundQuotes() throws CoreException {
		testWithVMArg("\"-Dfoo=foo bar\"", "foo bar");
	}
	/**
	 * Test a VM argument with quotes placed in a creative (non-standard, but
	 * valid) location
	 * Program output should be: foo bar
	 * @throws CoreException
	 */
	public void testVMArgCreativeQuotes() throws CoreException {
		testWithVMArg("-Dfoo=fo\"o b\"ar", "foo bar");
	}
	/**
	 * Test a VM argument with embedded quotes.
	 * Program output should be: "foo bar"
	 * @throws CoreException
	 */
	public void testVMArgEmbeddedQuotes() throws CoreException {
		testWithVMArg("-Dfoo=\"\\\"foo bar\\\"\"", "\"foo bar\"");
	}
	/**
	 * Test a VM argument with quotes placed in a creative (non-standard, but
	 * valid) location
	 * Program output should be: fo"o b"ar
	 * @throws CoreException
	 */
	public void testVMArgEmbeddedCreativeQuotes() throws CoreException {
		testWithVMArg("-Dfoo=fo\"\\\"o b\\\"\"ar", "fo\"o b\"ar");
	}

	/*
	 * Program argument tests
	 */
	/**
	 * Test a single program argument.
	 * Program output should be: foo
	 * @throws CoreException
	 */
	public void testProgramArgSingle() throws CoreException {
		testWithProgramArg("foo", "foo");
	}
	/**
	 * Test multiple program arguments.
	 * Program output should be: foo\nbar
	 * @throws CoreException
	 */
	public void testProgramArgMultiple() throws CoreException {
		testWithProgramArg("foo bar", "foobar");
	}
	/**
	 * Test a program argument with quotes in a valid location.
	 * Program output should be: foo
	 * @throws CoreException
	 */
	public void testProgramArgSimpleQuotes() throws CoreException {
		testWithProgramArg("\"foo\"", "foo");
	}
	/**
	 * Test a program argument with quotes in a standard location.
	 * Program output should be: foo bar
	 * @throws CoreException
	 */
	public void testProgramArgStandardQuotes() throws CoreException {
		testWithProgramArg("\"foo bar\"", "foo bar");
	}
	/**
	 * Test a program argument with quotes placed in a creative (non-standard,
	 * but valid) location.
	 * Program output should be: foo bar
	 * @throws CoreException
	 */
	public void testProgramArgCreativeQuotes() throws CoreException {
		testWithProgramArg("fo\"o b\"ar", "foo bar");
	}
	/**
	 * Test a program argument with embedded quotes in a standard location.
	 * Program output should be: "blah"
	 * @throws CoreException
	 */
	public void testProgramArgEmbeddedQuotes() throws CoreException {
		testWithProgramArg("\\\"blah\\\"", "\"blah\"");
	}
	/**
	 * Test a program argument with embedded quotes in a creative (non-standard,
	 * but valie) location.
	 * Program output should be: f"o"o
	 * @throws CoreException
	 */
	public void testProgramArgCreativeEmbeddedQuotes() throws CoreException {
		testWithProgramArg("f\\\"o\\\"o", "f\"o\"o");
	}

	/**
	 * Test a program argument with one empty string
     *
	 * Program output should be: 1
	 * @throws CoreException
	 */
	public void testProgramArgEmptyString() throws CoreException {
		testProgramArgCount("\"\"", "1");
		// assert that it's really the empty string:
		testWithProgramArg("\"\"", "");
	}

	/**
	 * Test a program with an empty string among other args.
	 *
	 * Program output should be: 4
	 * @throws CoreException
	 */
	public void testProgramArgEmptyStringWithOthers() throws CoreException {
		testProgramArgCount("word1 \"\" \"part1 part2\" word2", "4");
	}

	/**
	 * Test a program argument with one double quote. We should pass in the
	 * empty string to match Java console behavior.
	 *
	 * Program output should be: 1
	 * @throws CoreException
	 */
	public void testProgramArgOneQuote() throws CoreException {
		testProgramArgCount("\"", "1");
	}

	/**
	 * Runs the FooPropertyPrinter with the given VM arguments and checks for
	 * the given output.
	 * @param argString the VM arguments
	 * @param argValue the expected output
	 */
	private void testWithVMArg(String argString, String outputValue) throws CoreException {
		testOutput("FooPropertyPrinter", argString, null, outputValue);
	}

	/**
	 * Runs the ArgumentPrinter with the given program arguments
	 * @param argString
	 * @param outputValue
	 * @throws CoreException
	 */
	private void testWithProgramArg(String argString, String outputValue) throws CoreException {
		testOutput("ArgumentPrinter", null, argString, outputValue);
	}

	/**
	 * Runs the ArgumentCounter with the given program arguments
	 * @param argString
	 * @param outputValue
	 * @throws CoreException
	 */
	private void testProgramArgCount(String argString, String outputValue) throws CoreException {
		testOutput("ArgumentCounter", null, argString, outputValue);
	}

	/**
	 * Runs the given program with the given VM arguments and the given program arguments and
	 * asserts that the output matches the given output.
	 * @param mainTypeName the type to execute
	 * @param vmArgs the VM arguments to specify
	 * @param programArgs the program arguments to specify
	 * @param outputValue the expected output
	 */
	private void testOutput(String mainTypeName, String vmArgs, String programArgs, String outputValue) throws CoreException {
		ILaunchConfigurationWorkingCopy workingCopy = newConfiguration(null, "config1");

		workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, get14Project().getProject().getName());
		workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, mainTypeName);
		workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_STOP_IN_MAIN, true);
		workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, vmArgs);
		workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, programArgs);
		workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_ARGFILE, fUseArgfile);

		Map<String, String> env = getLaunchManager().getNativeEnvironment().entrySet().stream().filter(e -> !"JAVA_TOOL_OPTIONS".equals(e.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
		workingCopy.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, false);
		workingCopy.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, env);

		IVMInstall vm = JavaRuntime.getVMInstall(get14Project());
		assertNotNull("shold be able to get the default VM install from the 1.4 project", vm);
		if (fUseArgfile) {
			assertTrue("test requires a JVM >= 9", JavaRuntime.isModularJava(vm));
		}
		//workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH, JavaRuntime.newJREContainerPath(vm).toPortableString());

		// use 'java' instead of 'javaw' to launch tests (javaw is problematic on JDK1.4.2)
		Map<String, String> map = new HashMap<>(1);
		map.put(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, "java");
		workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, map);

		ConsoleArgumentOutputRetriever retriever = new ConsoleArgumentOutputRetriever();
		ConsoleLineTracker.setDelegate(retriever);
		IProcess process = null;
		ILaunch launch = null;
		String commandLine = null;
		try {
			HashSet<String> set = new HashSet<>();
			set.add(ILaunchManager.RUN_MODE);
			ensurePreferredDelegate(workingCopy, set);
			launch = workingCopy.launch(ILaunchManager.RUN_MODE, null);
			process = launch.getProcesses()[0];
			commandLine = process.getAttribute(IProcess.ATTR_CMDLINE);
		} catch (Exception e) {
			e.printStackTrace();
		}
		assertNotNull(commandLine);
		if (!fUseArgfile) {
			assertTrue("command line must not contain an @argfile", commandLine.indexOf(" @") == -1);
		} else {
			assertTrue("command line must contain an @argfile", commandLine.indexOf(" @") > -1);
		}
		try {
			String output = retriever.getOutput();
			// output if in error
			if (!outputValue.equals(output)) {
			    System.out.println();
			    System.out.println(getName());
				System.out.println("\tExpected:     " + outputValue);
				System.out.println("\tActual:       " + output);
				System.out.println("\tCommand Line: " + commandLine);
				if (fUseArgfile) {
					System.out.println("\tArgfile:      "
							+ readArgfile(commandLine).stream().collect(joining("\n\t              ")));
					System.out.println();
				}
			}
			assertEquals(outputValue, output);
		} finally {
			ConsoleLineTracker.setDelegate(null);
			if (process != null) {
				process.terminate();
			}
			if (launch != null) {
				getLaunchManager().removeLaunch(launch);
			}
		}
	}

	private List<String> readArgfile(String commandLine) {
		String[] arguments = DebugPlugin.parseArguments(commandLine);
		assertEquals("command line too long, only command @argfile expected", 2, arguments.length);
		String argfile = arguments[1];
		assertTrue("wrong command line, expected @argfile at index 1: " + commandLine, argfile != null && argfile.startsWith("@"));
		try {
			return Files.readAllLines(Path.of(argfile.substring(1)));
		} catch (IOException e) {
			throw new IllegalStateException("Error reading @argfile: " + argfile, e);
		}
	}

	/**
	 * Tests the default VM args
	 * @throws CoreException
	 */
	/*public void testDefaultVMArgs() throws CoreException {
	    IVMInstall install = JavaRuntime.getVMInstall(get14Project());
	    assertTrue("should be an IVMInstall2", install instanceof IVMInstall2);
	    IVMInstall2 vm2 = (IVMInstall2) install;
	    String prev = vm2.getVMArgs();
	    vm2.setVMArgs("-Dfoo=\"one two three\"");
	    try {
	        testWithVMArg(null, "one two three");
	    } finally {
	        vm2.setVMArgs(prev);
	    }
	}*/
}
