/*******************************************************************************
 *  Copyright (c) 2000, 2020 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.ant.tests.core.tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;

import org.eclipse.ant.core.AntCorePlugin;
import org.eclipse.ant.tests.core.AbstractAntTest;
import org.eclipse.ant.tests.core.testplugin.AntTestChecker;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.junit.Test;

public class OptionTests extends AbstractAntTest {

	protected static final String UNKNOWN_ARG = "Unknown argument: "; //$NON-NLS-1$
	protected static final String START_OF_HELP = "ant [options] [target [target2 [target3] ...]]"; //$NON-NLS-1$
	protected static final String VERSION = "Apache Ant(TM) version 1.10.9"; //$NON-NLS-1$
	protected static final String PLUGIN_VERSION = "org.apache.ant_1.10.9"; //$NON-NLS-1$

	/**
	 * Tests the "-help" option
	 */
	@Test
	public void testHelp() throws CoreException {
		run("TestForEcho.xml", new String[] { "-help" }); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("incorrect message number logged", 36, AntTestChecker.getDefault().getMessagesLoggedCount()); //$NON-NLS-1$
		assertTrue("Help is incorrect", getLastMessageLogged() != null //$NON-NLS-1$
				&& AntTestChecker.getDefault().getMessages().get(0).startsWith(START_OF_HELP));
	}

	/**
	 * Tests the "-h" option (help)
	 */
	@Test
	public void testMinusH() throws CoreException {
		run("TestForEcho.xml", new String[] { "-h" }); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("incorrect message number logged", 36, AntTestChecker.getDefault().getMessagesLoggedCount()); //$NON-NLS-1$
		assertTrue("Help is incorrect", getLastMessageLogged() != null //$NON-NLS-1$
				&& AntTestChecker.getDefault().getMessages().get(0).startsWith(START_OF_HELP));
	}

	/**
	 * Tests the "-version" option
	 */
	@Test
	public void testVersion() throws CoreException {
		run("TestForEcho.xml", new String[] { "-version" }); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("One message should have been logged", 1, AntTestChecker.getDefault().getMessagesLoggedCount()); //$NON-NLS-1$
		assertTrue("Version is incorrect", getLastMessageLogged().startsWith(VERSION)); //$NON-NLS-1$
	}

	/**
	 * Tests the "-projecthelp" option
	 */
	@Test
	public void testProjecthelp() throws CoreException {
		run("TestForEcho.xml", new String[] { "-projecthelp" }); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Incorrect number of messages", 4, AntTestChecker.getDefault().getMessagesLoggedCount()); //$NON-NLS-1$
		assertTrue("Project help is incorrect", getLastMessageLogged().startsWith("Default target:")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests the "-p" option (project help)
	 */
	@Test
	public void testMinusP() throws CoreException {
		run("TestForEcho.xml", new String[] { "-p" }); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Incorrect number of messages", 4, AntTestChecker.getDefault().getMessagesLoggedCount()); //$NON-NLS-1$
		assertTrue("Project help is incorrect", getLastMessageLogged().startsWith("Default target:")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests the "-projecthelp" option when it will not show as much (quite mode)
	 */
	@Test
	public void testProjecthelpQuiet() throws CoreException {
		run("TestForEcho.xml", new String[] { "-projecthelp", "-q" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		assertEquals(1, AntTestChecker.getDefault().getMessagesLoggedCount());
	}

	/**
	 * Tests the "-listener" option with a listener that is not an instance of
	 * BuildListener
	 */
	@Test
	public void testListenerBad() {
		CoreException ce = assertThrows("A core exception should have occurred wrappering a class cast exception", //$NON-NLS-1$
				CoreException.class, () -> run("TestForEcho.xml", new String[] { "-listener", "java.lang.String" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		String msg = ce.getMessage();
		assertTrue("Message incorrect!: " //$NON-NLS-1$
				+ msg,
				msg.equals(
						"java.lang.String which was specified to be a build listener is not an instance of org.apache.tools.ant.BuildListener.")); //$NON-NLS-1$
	}

	/**
	 * Tests passing an unrecognized argument
	 */
	@Test
	public void testUnknownArg() throws CoreException {
		run("TestForEcho.xml", new String[] { "-listenr" }); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Unrecognized option message should have been logged before successful build", //$NON-NLS-1$
				(AntTestChecker.getDefault().getMessagesLoggedCount() == 6)
						&& (getLoggedMessage(5).startsWith(UNKNOWN_ARG))
						&& (getLastMessageLogged().startsWith(BUILD_SUCCESSFUL)));
	}

	/**
	 * Tests specifying the -logfile with no arg
	 */
	@Test
	public void testLogFileWithNoArg() {
		assertThrows("You must specify a log file when using the -log argument", CoreException.class, //$NON-NLS-1$
				() -> run("TestForEcho.xml", new String[] { "-logfile" })); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests specifying the -logfile
	 */
	@Test
	public void testLogFile() throws CoreException, IOException {
		run("TestForEcho.xml", new String[] { "-logfile", "TestLogFile.txt" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		IFile file = checkFileExists("TestLogFile.txt"); //$NON-NLS-1$

		try (InputStream stream = file.getContents();
				InputStreamReader in = new InputStreamReader(new BufferedInputStream(stream))) {
			StringBuilder buffer = new StringBuilder();
			char[] readBuffer = new char[2048];
			int n = in.read(readBuffer);
			while (n > 0) {
				buffer.append(readBuffer, 0, n);
				n = in.read(readBuffer);
			}
			assertTrue("File should have started with Buildfile", buffer.toString().startsWith("Buildfile")); //$NON-NLS-1$ //$NON-NLS-2$
		}

	}

	/**
	 * Tests specifying the -logger with no arg
	 */
	@Test
	public void testLoggerWithNoArg() {
		assertThrows("You must specify a classname when using the -logger argument", CoreException.class, //$NON-NLS-1$
				() -> run("TestForEcho.xml", new String[] { "-logger" })); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests the "-logger" option with a logger that is not an instance of
	 * BuildLogger
	 */
	@Test
	public void testLoggerBad() {
		assertThrows("A core exception should have occurred wrappering a class cast exception", CoreException.class, //$NON-NLS-1$
				() -> run("TestForEcho.xml", new String[] { "-logger", "java.lang.String" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}

	/**
	 * Tests the "-logger" option with two loggers specified...only one is allowed
	 */
	@Test
	public void testTwoLoggers() {
		assertThrows("As only one logger can be specified", CoreException.class, () -> run("TestForEcho.xml", //$NON-NLS-1$ //$NON-NLS-2$
				new String[] { "-logger", "java.lang.String", "-q", "-logger", "java.lang.String" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
	}

	/**
	 * Tests specifying the -listener with no arg
	 */
	@Test
	public void testListenerWithNoArg() {
		assertThrows("You must specify a listeners when using the -listener argument ", CoreException.class, //$NON-NLS-1$
				() -> run("TestForEcho.xml", new String[] { "-listener" })); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests specifying the -listener with a class that will not be found
	 */
	@Test
	public void testListenerClassNotFound() {
		CoreException e = assertThrows("A CoreException should have occurred as the listener class will not be found", //$NON-NLS-1$
				CoreException.class, () -> run("TestForEcho.xml", new String[] { "-listener", "TestBuildListener" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		String message = e.getStatus().getException().getMessage();
		assertTrue("Should be ClassNotFoundException", //$NON-NLS-1$
				"java.lang.ClassNotFoundException: TestBuildListener".equals(message)); //$NON-NLS-1$

	}

	/**
	 * Tests specifying the -listener option
	 */
	@Test
	public void testListener() throws CoreException {
		run("TestForEcho.xml", new String[] { "-listener", ANT_TEST_BUILD_LISTENER }); //$NON-NLS-1$ //$NON-NLS-2$
		assertSuccessful();
		assertTrue("A listener should have been added named: " //$NON-NLS-1$
				+ ANT_TEST_BUILD_LISTENER,
				ANT_TEST_BUILD_LISTENER.equals(AntTestChecker.getDefault().getLastListener()));
	}

	/**
	 * Tests specifying the XmlLogger as a listener (bug 80435)
	 */
	@Test
	public void testXmlLoggerListener() throws CoreException, IOException {
		run("TestForEcho.xml", new String[] { "-listener", "org.apache.tools.ant.XmlLogger" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		assertSuccessful();

		// find the log file generated by the xml logger
		IFile file = checkFileExists("log.xml"); //$NON-NLS-1$
		InputStream stream = file.getContents();
		assertNotEquals(0, stream.available());
	}

	/**
	 * Tests specifying the -listener option multiple times...which is allowed
	 */
	@Test
	public void testListenerMultiple() throws CoreException {
		run("TestForEcho.xml", //$NON-NLS-1$
				new String[] { "-listener", ANT_TEST_BUILD_LISTENER, "-listener", ANT_TEST_BUILD_LISTENER }); //$NON-NLS-1$ //$NON-NLS-2$
		assertSuccessful();
		assertTrue("A listener should have been added named: " //$NON-NLS-1$
				+ ANT_TEST_BUILD_LISTENER,
				ANT_TEST_BUILD_LISTENER.equals(AntTestChecker.getDefault().getLastListener()));
		assertEquals("Two listeners should have been added", 2, AntTestChecker.getDefault().getListeners().size()); //$NON-NLS-1$
	}

	/**
	 * Tests specifying the -listener option multiple times, with one missing the
	 * arg
	 */
	@Test
	public void testListenerMultipleWithBad() {
		assertThrows("You must specify a listener for all -listener arguments ", CoreException.class, //$NON-NLS-1$
				() -> run("TestForEcho.xml", //$NON-NLS-1$
						new String[] { "-listener", ANT_TEST_BUILD_LISTENER, "-q", "-listener", "-verbose" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
	}

	/**
	 * Tests specifying the -buildfile with no arg
	 */
	@Test
	public void testBuildFileWithNoArg() {
		assertThrows("You must specify a buildfile when using the -buildfile argument", CoreException.class, //$NON-NLS-1$
				() -> run("TestForEcho.xml", new String[] { "-buildfile" })); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests specifying the -buildfile
	 */
	@Test
	public void testBuildFile() throws CoreException {
		String buildFileName = getProject().getFolder("buildfiles").getFile("echoing.xml").getLocation().toFile() //$NON-NLS-1$ //$NON-NLS-2$
				.getAbsolutePath();
		run("TestForEcho.xml", new String[] { "-buildfile", buildFileName }, false, "buildfiles"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		assertEquals("Should have been 1 tasks, was: " //$NON-NLS-1$
				+ AntTestChecker.getDefault().getTaskStartedCount(), 1,
				AntTestChecker.getDefault().getTaskStartedCount());
	}

	/**
	 * Tests specifying a target at the command line that does not exist.
	 * 
	 * @since 3.6 this will not fail - the default target will be run instead
	 * @since 3.8 this will fail as there are no more known targets
	 */
	@Test
	public void testSpecifyBadTargetAsArg() throws CoreException {
		run("TestForEcho.xml", new String[] { "echo2" }, false); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Should be an unknown target message", //$NON-NLS-1$
				AntTestChecker.getDefault().getLoggedMessage(1).contains("Unknown target")); //$NON-NLS-1$
		assertTrue("Should be an unknown target message", //$NON-NLS-1$
				AntTestChecker.getDefault().getLoggedMessage(1).contains("echo2")); //$NON-NLS-1$
		assertTrue("Should be a no known target message", //$NON-NLS-1$
				AntTestChecker.getDefault().getLoggedMessage(0).contains("No known target specified.")); //$NON-NLS-1$
		assertEquals("Should not have run any targets", 0, AntTestChecker.getDefault().getTargetsStartedCount()); //$NON-NLS-1$
	}

	/**
	 * Tests specifying both a non-existent target and an existent target in the
	 * command line
	 * 
	 */
	@Test
	public void testSpecifyBothBadAndGoodTargetsAsArg() throws CoreException {
		run("TestForEcho.xml", new String[] { "echo2", "Test for Echo" }, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		assertTrue("Should be an unknown target message", //$NON-NLS-1$
				AntTestChecker.getDefault().getLoggedMessage(5).contains("Unknown target")); //$NON-NLS-1$
		assertTrue("Should be an unknown target message", //$NON-NLS-1$
				AntTestChecker.getDefault().getLoggedMessage(5).contains("echo2")); //$NON-NLS-1$
		assertEquals("Should have run the Test for Echo target", 5, //$NON-NLS-1$
				AntTestChecker.getDefault().getTargetsStartedCount());
	}

	/**
	 * Tests specifying a target at the command line
	 */
	@Test
	public void testSpecifyTargetAsArg() throws CoreException {
		run("echoing.xml", new String[] { "echo3" }, false); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("3 messages should have been logged; was " //$NON-NLS-1$
				+ AntTestChecker.getDefault().getMessagesLoggedCount(), 3,
				AntTestChecker.getDefault().getMessagesLoggedCount());
		assertSuccessful();
	}

	/**
	 * Tests specifying a target at the command line with other options
	 */
	@Test
	public void testSpecifyTargetAsArgWithOtherOptions() throws CoreException {
		run("echoing.xml", new String[] { "-logfile", "TestLogFile.txt", "echo3" }, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertEquals("4 messages should have been logged; was " //$NON-NLS-1$
				+ AntTestChecker.getDefault().getMessagesLoggedCount(), 4,
				AntTestChecker.getDefault().getMessagesLoggedCount());
		List<String> messages = AntTestChecker.getDefault().getMessages();
		// ensure that echo3 target executed and only that target
		assertTrue("echo3 target not executed", messages.get(2).equals("echo3")); //$NON-NLS-1$ //$NON-NLS-2$
		assertSuccessful();
	}

	/**
	 * Tests specifying targets at the command line with other options
	 */
	@Test
	public void testSpecifyTargetsAsArgWithOtherOptions() throws CoreException {
		run("echoing.xml", new String[] { "-logfile", "TestLogFile.txt", "echo2", "echo3" }, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
		assertEquals("5 messages should have been logged; was " //$NON-NLS-1$
				+ AntTestChecker.getDefault().getMessagesLoggedCount(), 5,
				AntTestChecker.getDefault().getMessagesLoggedCount());
		List<String> messages = AntTestChecker.getDefault().getMessages();
		// ensure that echo2 target executed
		assertTrue("echo2 target not executed", messages.get(2).equals("echo2")); //$NON-NLS-1$ //$NON-NLS-2$
		assertSuccessful();
	}

	/**
	 * Tests specifying a target at the command line and quiet reporting
	 */
	@Test
	public void testSpecifyTargetAsArgAndQuiet() throws CoreException {
		run("echoing.xml", new String[] { "-logfile", "TestLogFile.txt", "echo3", "-quiet" }, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
		assertEquals("2 messages should have been logged; was " //$NON-NLS-1$
				+ AntTestChecker.getDefault().getMessagesLoggedCount(), 2,
				AntTestChecker.getDefault().getMessagesLoggedCount());
	}

	/**
	 * Tests properties using "-D"
	 */
	@Test
	public void testMinusD() throws CoreException {
		run("echoing.xml", new String[] { "-DAntTests=testing", "-Declipse.is.cool=true" }, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		assertSuccessful();
		assertTrue("eclipse.is.cool should have been set as true", //$NON-NLS-1$
				"true".equals(AntTestChecker.getDefault().getUserProperty("eclipse.is.cool"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("AntTests should have a value of testing", //$NON-NLS-1$
				"testing".equals(AntTestChecker.getDefault().getUserProperty("AntTests"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("my.name was not set and should be null", AntTestChecker.getDefault().getUserProperty("my.name")); //$NON-NLS-1$ //$NON-NLS-2$

	}

	/**
	 * Tests properties using "-D" and "-d" to specify debug
	 */
	@Test
	public void testMinusDMinusd() throws CoreException {
		run("echoing.xml", new String[] { "-d", "-DAntTests=testing", "-Declipse.is.cool=true" }, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertSuccessful();
		assertTrue("eclipse.is.cool should have been set as true", //$NON-NLS-1$
				"true".equals(AntTestChecker.getDefault().getUserProperty("eclipse.is.cool"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("AntTests should have a value of testing", //$NON-NLS-1$
				"testing".equals(AntTestChecker.getDefault().getUserProperty("AntTests"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("my.name was not set and should be null", AntTestChecker.getDefault().getUserProperty("my.name")); //$NON-NLS-1$ //$NON-NLS-2$

	}

	@Test
	public void testMinusDAndGlobalProperties() throws CoreException {
		run("echoing.xml", new String[] { "-DAntTests=testing", "-Declipse.is.cool=true" }, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		assertSuccessful();
		assertTrue("eclipse.running should have been set as true", //$NON-NLS-1$
				"true".equals(AntTestChecker.getDefault().getUserProperty("eclipse.running"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertNotNull("eclipse.home should have been set", AntTestChecker.getDefault().getUserProperty("eclipse.home")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests specifying a property such as "-D=emptyStringIsMyName Bug 37007
	 */
	@Test
	public void testMinusDEmpty() throws CoreException {
		run("echoing.xml", new String[] { "-D=emptyStringIsMyName", "-Declipse.is.cool=true" }, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		assertSuccessful();
		assertTrue("eclipse.is.cool should have been set as true", //$NON-NLS-1$
				"true".equals(AntTestChecker.getDefault().getUserProperty("eclipse.is.cool"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("\"\" should have a value of emptyStringIsMyName", //$NON-NLS-1$
				"emptyStringIsMyName".equals(AntTestChecker.getDefault().getUserProperty(""))); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("my.name was not set and should be null", AntTestChecker.getDefault().getUserProperty("my.name")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests specifying properties that contain spaces Bug 37094
	 */
	@Test
	public void testMinusDWithSpaces() throws CoreException {
		run("echoing.xml", new String[] { "-DAntTests= testing", "-Declipse.is.cool=    true" }, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		assertSuccessful();
		assertTrue("eclipse.is.cool should have been set as true", //$NON-NLS-1$
				"true".equals(AntTestChecker.getDefault().getUserProperty("eclipse.is.cool"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("AntTests should have a value of testing", //$NON-NLS-1$
				"testing".equals(AntTestChecker.getDefault().getUserProperty("AntTests"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("my.name was not set and should be null", AntTestChecker.getDefault().getUserProperty("my.name")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests specifying properties when the user has incorrectly specified "-Debug"
	 * Bug 40935
	 */
	@Test
	public void testPropertiesWithMinusDebug() throws CoreException {
		run("echoing.xml", new String[] { "-Debug", "-DAntTests= testing", "-Declipse.is.cool=    true" }, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("\"-Debug\" should be flagged as an unknown argument", //$NON-NLS-1$
				"Unknown argument: -Debug".equals(AntTestChecker.getDefault().getMessages().get(0))); //$NON-NLS-1$
		assertSuccessful();
		assertTrue("eclipse.is.cool should have been set as true", //$NON-NLS-1$
				"true".equals(AntTestChecker.getDefault().getUserProperty("eclipse.is.cool"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("AntTests should have a value of testing", //$NON-NLS-1$
				"testing".equals(AntTestChecker.getDefault().getUserProperty("AntTests"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("my.name was not set and should be null", AntTestChecker.getDefault().getUserProperty("my.name")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests when the user has incorrectly specified "-Debug" Bug 40935
	 */
	@Test
	public void testMinusDebug() throws CoreException {
		run("echoing.xml", new String[] { "-Debug" }); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("\"-Debug\" should be flagged as an unknown argument", //$NON-NLS-1$
				"Unknown argument: -Debug".equals(AntTestChecker.getDefault().getMessages().get(0))); //$NON-NLS-1$
		assertSuccessful();
	}

	@Test
	public void testPropertyFileWithNoArg() {
		assertThrows("You must specify a property filename when using the -propertyfile argument", CoreException.class, //$NON-NLS-1$
				() -> run("TestForEcho.xml", new String[] { "-propertyfile" })); //$NON-NLS-1$ //$NON-NLS-2$
		String msg = AntTestChecker.getDefault().getMessages().get(0);
		assertTrue("Message incorrect!: " + msg, //$NON-NLS-1$
				msg.equals("You must specify a property filename when using the -propertyfile argument")); //$NON-NLS-1$
	}

	/**
	 * A build should succeed when a property file is not found. The error is
	 * reported and the build continues.
	 */
	@Test
	public void testPropertyFileFileNotFound() throws CoreException {

		run("TestForEcho.xml", new String[] { "-propertyfile", "qq.txt" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		assertSuccessful();
		String msg = AntTestChecker.getDefault().getMessages().get(0);
		assertTrue("Message incorrect!: " + msg, msg.startsWith("Could not load property file:")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	@Test
	public void testPropertyFile() throws CoreException {
		run("TestForEcho.xml", new String[] { "-propertyfile", getPropertyFileName() }); //$NON-NLS-1$ //$NON-NLS-2$
		assertSuccessful();
		assertTrue("eclipse.is.cool should have been set as Yep", //$NON-NLS-1$
				"Yep".equals(AntTestChecker.getDefault().getUserProperty("eclipse.is.cool"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("AntTests should have a value of testing", //$NON-NLS-1$
				"testing from properties file".equals(AntTestChecker.getDefault().getUserProperty("AntTests"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("my.name was not set and should be null", AntTestChecker.getDefault().getUserProperty("my.name")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	@Test
	public void testPropertyFileWithMinusDTakingPrecedence() throws CoreException {
		run("echoing.xml", //$NON-NLS-1$
				new String[] { "-propertyfile", getPropertyFileName(), "-DAntTests=testing", "-Declipse.is.cool=true" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				false);
		assertSuccessful();
		assertTrue("eclipse.is.cool should have been set as true", //$NON-NLS-1$
				"true".equals(AntTestChecker.getDefault().getUserProperty("eclipse.is.cool"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("AntTests should have a value of testing", //$NON-NLS-1$
				"testing".equals(AntTestChecker.getDefault().getUserProperty("AntTests"))); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull("my.name was not set and should be null", AntTestChecker.getDefault().getUserProperty("my.name")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	@Test
	public void testInputHandlerWithNoArg() {
		CoreException ce = assertThrows("You must specify a classname when using the -inputhandler argument", //$NON-NLS-1$
				CoreException.class, () -> run("TestForEcho.xml", new String[] { "-inputhandler" })); //$NON-NLS-1$ //$NON-NLS-2$
		String msg = ce.getMessage();
		assertTrue("Message incorrect!: " + msg, //$NON-NLS-1$
				msg.equals("You must specify a classname when using the -inputhandler argument")); //$NON-NLS-1$
	}

	/**
	 * Tests the "-inputhandler" option with two handlers specified...only one is
	 * allowed
	 */
	@Test
	public void testInputHandlerMultiple() {
		CoreException ce = assertThrows("As only one input handler can be specified", CoreException.class, //$NON-NLS-1$
				() -> run("TestForEcho.xml", //$NON-NLS-1$
						new String[] { "-inputhandler", "org.apache.tools.ant.input.DefaultInputHandler", "-q", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
								"-inputhandler", //$NON-NLS-1$
								"org.apache.tools.ant.input.DefaultInputHandler" })); //$NON-NLS-1$
		String msg = ce.getMessage();
		assertTrue("Message incorrect!: " + msg, msg.equals("Only one input handler class may be specified.")); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests the "-inputhandler" option with a input handler that is not an instance
	 * of InputHandler
	 */
	@Test
	public void testInputHandlerBad() {
		CoreException ce = assertThrows("Incorrect inputhandler", CoreException.class, //$NON-NLS-1$
				() -> run("TestForEcho.xml", new String[] { "-inputhandler", "java.lang.StringBuffer" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		String msg = ce.getMessage();
		assertTrue("Message incorrect!: " //$NON-NLS-1$
				+ msg,
				msg.equals(
						"The specified input handler class java.lang.StringBuffer does not implement the org.apache.tools.ant.input.InputHandler interface")); //$NON-NLS-1$
	}

	/**
	 * Tests the "-inputhandler" option with a input handler that is not a defined
	 * class
	 */
	@Test
	public void testInputHandlerBad2() {
		CoreException ce = assertThrows("Incorrect inputhandler", CoreException.class, //$NON-NLS-1$
				() -> run("TestForEcho.xml", new String[] { "-inputhandler", "ja.lang.StringBuffer" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		String msg = ce.getMessage();
		assertTrue("Message incorrect!: " + msg, //$NON-NLS-1$
				msg.startsWith("Unable to instantiate specified input handler class ja.lang.StringBuffer")); //$NON-NLS-1$
	}

	/**
	 * Tests the "-inputhandler" option with a test input handler and the -noinput
	 * option
	 */
	@Test
	public void testInputHandlerWithMinusNoInput() {
		CoreException ce = assertThrows("Build should have failed", CoreException.class, //$NON-NLS-1$
				() -> run("input.xml", new String[] { "-inputhandler", //$NON-NLS-1$ //$NON-NLS-2$
						"org.eclipse.ant.tests.core.support.inputHandlers.AntTestInputHandler", "-noinput" })); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Message incorrect: " //$NON-NLS-1$
				+ ce.getMessage(),
				ce.getMessage().endsWith(
						"Unable to respond to input request likely as a result of specifying the -noinput command")); //$NON-NLS-1$
	}

	/**
	 * Tests the -noinput option with the default input handler
	 */
	@Test
	public void testMinusNoInput() {
		CoreException ce = assertThrows("Build should have failed", CoreException.class, //$NON-NLS-1$
				() -> run("input.xml", new String[] { "-noinput" })); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Message incorrect: " + ce.getMessage(), //$NON-NLS-1$
				ce.getMessage().endsWith("Failed to read input from Console.")); //$NON-NLS-1$
	}

	/**
	 * Tests the "-inputhandler" option with a test input handler Order after the
	 * noinput tests so that we test we are resetting the system property
	 */
	@Test
	public void testInputHandler() throws CoreException {

		run("input.xml", new String[] { "-inputhandler", //$NON-NLS-1$ //$NON-NLS-2$
				"org.eclipse.ant.tests.core.support.inputHandlers.AntTestInputHandler" }); //$NON-NLS-1$
		assertSuccessful();
		String msg = AntTestChecker.getDefault().getMessages().get(1);
		assertTrue("Message incorrect: " + msg, msg.equals("testing handling input requests")); //$NON-NLS-1$ //$NON-NLS-2$

	}

	/**
	 * Tests the "-diagnostics" option with no ANT_HOME set bug 25693
	 */
	@Test
	public void testDiagnosticsWithNoAntHome() throws CoreException {
		try {
			AntCorePlugin.getPlugin().getPreferences().setAntHome(null);
			run("input.xml", new String[] { "-diagnostics" }); //$NON-NLS-1$ //$NON-NLS-2$

			String msg = AntTestChecker.getDefault().getMessages().get(0);
			assertTrue("Message incorrect: " + msg, msg.equals("------- Ant diagnostics report -------")); //$NON-NLS-1$ //$NON-NLS-2$
		} finally {
			restorePreferenceDefaults();
		}
	}

	/**
	 * Tests the "-diagnostics" option with ANT_HOME set bug 25693
	 */
	@Test
	public void testDiagnostics() throws CoreException {

		try {
			run("input.xml", new String[] { "-diagnostics" }); //$NON-NLS-1$ //$NON-NLS-2$
		} finally {
			restorePreferenceDefaults();
		}
		// we are looking for the ant.home entry
		List<String> messages = AntTestChecker.getDefault().getMessages();
		String msg = messages.get(17);
		// msg depends on whether self hosting testing or build testing
		assertTrue("Message incorrect: " + msg, checkAntHomeMessage(msg)); //$NON-NLS-1$
	}

	private boolean checkAntHomeMessage(String message) {
		String msg = message;
		if (msg.endsWith("org.apache.ant")) { //$NON-NLS-1$
			return true;
		}

		if (msg.endsWith(PLUGIN_VERSION)) {
			return true;
		}

		// org.apache.ant_1.7.1.v200704241635
		int index = msg.lastIndexOf('.');
		if (index > 0) {
			msg = msg.substring(0, index);
		}
		return msg.endsWith(PLUGIN_VERSION);
	}

	/**
	 * Tests the "-quiet" still reports build successful bug 34488
	 */
	@Test
	public void testMinusQuiet() throws CoreException {
		run("TestForEcho.xml", new String[] { "-quiet" }); //$NON-NLS-1$ //$NON-NLS-2$
		assertSuccessful();
	}

	/**
	 * Tests the "-keep-going" option
	 */
	@Test
	public void testMinusKeepGoing() {
		assertThrows("The build should have failed", CoreException.class, //$NON-NLS-1$
				() -> run("failingTarget.xml", new String[] { "-keep-going" }, false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("4 messages should have been logged; was " //$NON-NLS-1$
				+ AntTestChecker.getDefault().getMessagesLoggedCount(), 4,
				AntTestChecker.getDefault().getMessagesLoggedCount());
		assertTrue("Incorrect message:" //$NON-NLS-1$
				+ AntTestChecker.getDefault().getLoggedMessage(1),
				"Still echo on failure".equals(AntTestChecker.getDefault().getLoggedMessage(1))); //$NON-NLS-1$
	}

	/**
	 * Tests the "-k" option
	 */
	@Test
	public void testMinusK() {
		assertThrows("The build should have failed", CoreException.class, //$NON-NLS-1$
				() -> run("failingTarget.xml", new String[] { "-k" }, false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("4 messages should have been logged; was " //$NON-NLS-1$
				+ AntTestChecker.getDefault().getMessagesLoggedCount(), 4,
				AntTestChecker.getDefault().getMessagesLoggedCount());
		assertTrue("Incorrect message:" //$NON-NLS-1$
				+ AntTestChecker.getDefault().getLoggedMessage(1),
				"Still echo on failure".equals(AntTestChecker.getDefault().getLoggedMessage(1))); //$NON-NLS-1$
	}
}