/*******************************************************************************
 *  Copyright (c) 2000, 2015 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.debug.tests.core;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.runtime.CoreException;
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();

	private class ConsoleArgumentOutputRetriever implements IConsoleLineTrackerExtension {

		StringBuffer 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 StringBuffer();
			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);
                buffer.append(document.get(line.getOffset(), line.getLength()));
			} 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);
		IVMInstall vm = JavaRuntime.getVMInstall(get14Project());
		assertNotNull("shold be able to get the default VM install from the 1.4 project", 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<String, String>(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;
		try {
			HashSet<String> set = new HashSet<String>();
			set.add(ILaunchManager.RUN_MODE);
			ensurePreferredDelegate(workingCopy, set);
			launch = workingCopy.launch(ILaunchManager.RUN_MODE, null);
			process = launch.getProcesses()[0];
		} catch (Exception e) {
			e.printStackTrace();
		}
		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);
			}
			assertEquals(outputValue, output);
		} finally {
			ConsoleLineTracker.setDelegate(null);
			if (process != null) {
				process.terminate();
			}
			if (launch != null) {
				getLaunchManager().removeLaunch(launch);
			}
		}
	}

	/**
	 * 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);
	    }
	}*/
}
