/*******************************************************************************
 *  Copyright (c) 2003, 2013 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.ui.testplugin;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import junit.framework.TestCase;

import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.IAntUIPreferenceConstants;
import org.eclipse.ant.internal.ui.model.AntModel;
import org.eclipse.ant.tests.ui.debug.TestAgainException;
import org.eclipse.ant.tests.ui.editor.support.TestLocationProvider;
import org.eclipse.ant.tests.ui.editor.support.TestProblemRequestor;
import org.eclipse.core.externaltools.internal.IExternalToolConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugEvent;
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.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.swt.graphics.Color;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.IHyperlink;
import org.eclipse.ui.internal.console.ConsoleHyperlinkPosition;
import org.eclipse.ui.internal.console.IOConsolePartition;
import org.eclipse.ui.intro.IIntroManager;
import org.eclipse.ui.intro.IIntroPart;
import org.eclipse.ui.progress.UIJob;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Abstract Ant UI test class
 */
public abstract class AbstractAntUITest extends TestCase {

	public static String ANT_EDITOR_ID = "org.eclipse.ant.ui.internal.editor.AntEditor"; //$NON-NLS-1$
	private boolean welcomeClosed = false;
	private IDocument currentDocument;

	/**
	 * Constructor
	 * 
	 * @param name
	 */
	public AbstractAntUITest(String name) {
		super(name);
	}

	/**
	 * Returns the {@link IFile} for the given build file name
	 * 
	 * @param buildFileName
	 * @return the associated {@link IFile} for the given build file name
	 */
	protected IFile getIFile(String buildFileName) {
		return getProject().getFolder("buildfiles").getFile(buildFileName); //$NON-NLS-1$
	}

	/**
	 * Returns the {@link File} for the given build file name
	 * 
	 * @param buildFileName
	 * @return the {@link File} for the given build file name
	 */
	protected File getBuildFile(String buildFileName) {
		IFile file = getIFile(buildFileName);
		assertTrue("Could not find build file named: " + buildFileName, file.exists()); //$NON-NLS-1$
		return file.getLocation().toFile();
	}

	/**
	 * When a test throws the 'try again' exception, try it again.
	 * 
	 * @see junit.framework.TestCase#runBare()
	 */
	@Override
	public void runBare() throws Throwable {
		boolean tryAgain = true;
		int attempts = 0;
		while (tryAgain) {
			try {
				attempts++;
				super.runBare();
				tryAgain = false;
			}
			catch (TestAgainException e) {
				System.out.println("Test failed attempt " + attempts + ". Re-testing: " + this.getName()); //$NON-NLS-1$ //$NON-NLS-2$ 
				e.printStackTrace();
				if (attempts > 5) {
					tryAgain = false;
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see junit.framework.TestCase#setUp()
	 */
	@Override
	protected void setUp() throws Exception {
		super.setUp();
		assertProject();
		assertWelcomeScreenClosed();
	}

	/**
	 * Ensure the welcome screen is closed because in 4.x the debug perspective opens a giant fast-view causing issues
	 * 
	 * @throws Exception
	 * @since 3.8
	 */
	void assertWelcomeScreenClosed() throws Exception {
		if (!welcomeClosed && PlatformUI.isWorkbenchRunning()) {
			final IWorkbench wb = PlatformUI.getWorkbench();
			if (wb != null) {
				UIJob job = new UIJob("close welcome screen for Ant test suite") { //$NON-NLS-1$
					@Override
					public IStatus runInUIThread(IProgressMonitor monitor) {
						IWorkbenchWindow window = wb.getActiveWorkbenchWindow();
						if (window != null) {
							IIntroManager im = wb.getIntroManager();
							IIntroPart intro = im.getIntro();
							if (intro != null) {
								welcomeClosed = im.closeIntro(intro);
							}
						}
						return Status.OK_STATUS;
					}
				};
				job.setPriority(Job.INTERACTIVE);
				job.setSystem(true);
				job.schedule();
			}
		}
	}

	/**
	 * Asserts that the testing project has been setup in the test workspace
	 * 
	 * @throws Exception
	 * 
	 * @since 3.5
	 */
	public static void assertProject() throws Exception {
		IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ProjectHelper.PROJECT_NAME);
		if (!pro.exists()) {
			// create project and import build files and support files
			IProject project = ProjectHelper.createProject(ProjectHelper.PROJECT_NAME);
			IFolder folder = ProjectHelper.addFolder(project, "buildfiles"); //$NON-NLS-1$
			ProjectHelper.addFolder(project, "launchConfigurations"); //$NON-NLS-1$
			File root = AntUITestPlugin.getDefault().getFileInPlugin(ProjectHelper.TEST_BUILDFILES_DIR);
			ProjectHelper.importFilesFromDirectory(root, folder.getFullPath(), null);

			ProjectHelper.createLaunchConfigurationForBoth("echoing"); //$NON-NLS-1$
			ProjectHelper.createLaunchConfigurationForBoth("102282"); //$NON-NLS-1$
			ProjectHelper.createLaunchConfigurationForBoth("74840"); //$NON-NLS-1$
			ProjectHelper.createLaunchConfigurationForBoth("failingTarget"); //$NON-NLS-1$
			ProjectHelper.createLaunchConfiguration("build"); //$NON-NLS-1$
			ProjectHelper.createLaunchConfiguration("bad"); //$NON-NLS-1$
			ProjectHelper.createLaunchConfiguration("importRequiringUserProp"); //$NON-NLS-1$
			ProjectHelper.createLaunchConfigurationForSeparateVM("echoPropertiesSepVM", "echoProperties"); //$NON-NLS-1$ //$NON-NLS-2$
			ProjectHelper.createLaunchConfigurationForSeparateVM("extensionPointSepVM", null); //$NON-NLS-1$
			ProjectHelper.createLaunchConfigurationForSeparateVM("extensionPointTaskSepVM", null); //$NON-NLS-1$
			ProjectHelper.createLaunchConfigurationForSeparateVM("extensionPointTypeSepVM", null); //$NON-NLS-1$
			ProjectHelper.createLaunchConfigurationForSeparateVM("input", null); //$NON-NLS-1$
			ProjectHelper.createLaunchConfigurationForSeparateVM("environmentVar", null); //$NON-NLS-1$

			ProjectHelper.createLaunchConfigurationForBoth("breakpoints"); //$NON-NLS-1$
			ProjectHelper.createLaunchConfigurationForBoth("debugAntCall"); //$NON-NLS-1$
			ProjectHelper.createLaunchConfigurationForBoth("96022"); //$NON-NLS-1$
			ProjectHelper.createLaunchConfigurationForBoth("macrodef"); //$NON-NLS-1$
			ProjectHelper.createLaunchConfigurationForBoth("85769"); //$NON-NLS-1$

			ProjectHelper.createLaunchConfiguration("big", ProjectHelper.PROJECT_NAME + "/buildfiles/performance/build.xml"); //$NON-NLS-1$ //$NON-NLS-2$

			// do not show the Ant build failed error dialog
			AntUIPlugin.getDefault().getPreferenceStore().setValue(IAntUIPreferenceConstants.ANT_ERROR_DIALOG, false);
		}
	}

	/**
	 * Returns the 'AntUITests' project.
	 * 
	 * @return the test project
	 */
	protected static IProject getProject() {
		return ResourcesPlugin.getWorkspace().getRoot().getProject(ProjectHelper.PROJECT_NAME);
	}

	/**
	 * Returns the underlying {@link IDocument} for the given file name
	 * 
	 * @param fileName
	 * @return the underlying {@link IDocument} for the given file name
	 */
	protected IDocument getDocument(String fileName) {
		File file = getBuildFile(fileName);
		InputStream in;
		try {
			in = new FileInputStream(file);
		}
		catch (FileNotFoundException e) {
			return null;
		}
		String initialContent = getStreamContentAsString(in);
		return new Document(initialContent);
	}

	/**
	 * Returns the contents of the given {@link InputStream} as a {@link String}
	 * 
	 * @param inputStream
	 * @return the {@link InputStream} as a {@link String}
	 */
	protected String getStreamContentAsString(InputStream inputStream) {
		InputStreamReader reader;
		try {
			reader = new InputStreamReader(inputStream, ResourcesPlugin.getEncoding());
		}
		catch (UnsupportedEncodingException e) {
			AntUIPlugin.log(e);
			return ""; //$NON-NLS-1$
		}
		BufferedReader tempBufferedReader = new BufferedReader(reader);

		return getReaderContentAsString(tempBufferedReader);
	}

	/**
	 * Returns the contents of the given {@link BufferedReader} as a {@link String}
	 * 
	 * @param bufferedReader
	 * @return the contents of the given {@link BufferedReader} as a {@link String}
	 */
	protected String getReaderContentAsStringNew(BufferedReader bufferedReader) {
		StringBuffer result = new StringBuffer();
		try {
			char[] readBuffer = new char[2048];
			int n = bufferedReader.read(readBuffer);
			while (n > 0) {
				result.append(readBuffer, 0, n);
				n = bufferedReader.read(readBuffer);
			}
		}
		catch (IOException e) {
			AntUIPlugin.log(e);
			return null;
		}

		return result.toString();
	}

	/**
	 * Returns the contents of the given {@link BufferedReader} as a {@link String}
	 * 
	 * @param bufferedReader
	 * @return the contents of the given {@link BufferedReader} as a {@link String}
	 */
	protected String getReaderContentAsString(BufferedReader bufferedReader) {
		StringBuffer result = new StringBuffer();
		try {
			String line = bufferedReader.readLine();

			while (line != null) {
				if (result.length() != 0) {
					result.append(System.getProperty("line.separator")); //$NON-NLS-1$
				}
				result.append(line);
				line = bufferedReader.readLine();
			}
		}
		catch (IOException e) {
			AntUIPlugin.log(e);
			return null;
		}

		return result.toString();
	}

	/**
	 * Returns the {@link AntModel} for the given file name
	 * 
	 * @param fileName
	 * @return the {@link AntModel} for the given file name
	 */
	protected AntModel getAntModel(String fileName) {
		currentDocument = getDocument(fileName);
		AntModel model = new AntModel(currentDocument, new TestProblemRequestor(), new TestLocationProvider(getBuildFile(fileName)));
		model.reconcile();
		return model;
	}

	/**
	 * @return the current {@link IDocument} context
	 */
	public IDocument getCurrentDocument() {
		return currentDocument;
	}

	/**
	 * Allows the current {@link IDocument} context to be set. This method accepts <code>null</code>
	 * 
	 * @param currentDocument
	 */
	public void setCurrentDocument(IDocument currentDocument) {
		this.currentDocument = currentDocument;
	}

	/**
	 * Launches the Ant build with the build file name (no extension).
	 * 
	 * @param buildFileName
	 *            the ant build file name
	 */
	protected void launch(String buildFileName) throws CoreException {
		ILaunchConfiguration config = getLaunchConfiguration(buildFileName);
		assertNotNull("Could not locate launch configuration for " + buildFileName, config); //$NON-NLS-1$
		launchAndTerminate(config, 20000);
	}

	/**
	 * Launches the Ant build with the build file name (no extension).
	 * 
	 * @param buildFileName
	 *            the build file
	 * @param arguments
	 *            the ant arguments
	 */
	protected void launch(String buildFileName, String arguments) throws CoreException {
		ILaunchConfiguration config = getLaunchConfiguration(buildFileName);
		assertNotNull("Could not locate launch configuration for " + buildFileName, config); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy copy = config.getWorkingCopy();
		copy.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, arguments);
		launchAndTerminate(copy, 20000);
	}

	/**
	 * Launches the Ant build in debug output mode with the build file name (no extension).
	 * 
	 * @param mainTypeName
	 *            the program to launch
	 * @return thread in which the first suspend event occurred
	 */
	protected void launchWithDebug(String buildFileName) throws CoreException {
		ILaunchConfiguration config = getLaunchConfiguration(buildFileName);
		assertNotNull("Could not locate launch configuration for " + buildFileName, config); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy copy = config.getWorkingCopy();
		copy.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, "-debug"); //$NON-NLS-1$
		launchAndTerminate(copy, 10000);
	}

	/**
	 * Returns the launch configuration for the given build file
	 * 
	 * @param buildFileName
	 *            build file to launch
	 * @see ProjectCreationDecorator
	 */
	protected ILaunchConfiguration getLaunchConfiguration(String buildFileName) {
		IFile file = getJavaProject().getProject().getFolder("launchConfigurations").getFile(buildFileName + ".launch"); //$NON-NLS-1$ //$NON-NLS-2$
		ILaunchConfiguration config = getLaunchManager().getLaunchConfiguration(file);
		assertTrue("Could not find launch configuration for " + buildFileName, config.exists()); //$NON-NLS-1$
		return config;
	}

	/**
	 * Returns the content of the specified file as <code>String</code>.
	 */
	protected String getFileContentAsString(File aFile) throws FileNotFoundException {
		InputStream stream = new FileInputStream(aFile);
		InputStreamReader reader = new InputStreamReader(stream);
		BufferedReader bufferedReader = new BufferedReader(reader);

		return getReaderContentAsString(bufferedReader);
	}

	/**
	 * @return a new SAX parser instrance
	 */
	protected SAXParser getSAXParser() {
		SAXParser parser = null;
		try {
			parser = SAXParserFactory.newInstance().newSAXParser();
		}
		catch (ParserConfigurationException e) {
			AntUIPlugin.log(e);
		}
		catch (SAXException e) {
			AntUIPlugin.log(e);
		}
		return parser;
	}

	/**
	 * Parses the given input stream with the given parser using the given handler
	 * 
	 * @param stream
	 * @param parser
	 * @param handler
	 * @param editedFile
	 * @throws IOException
	 * @throws SAXException
	 */
	protected void parse(InputStream stream, SAXParser parser, DefaultHandler handler, File editedFile) throws SAXException, IOException {
		InputSource inputSource = new InputSource(stream);
		if (editedFile != null) {
			// needed for resolving relative external entities
			inputSource.setSystemId(editedFile.getAbsolutePath());
		}
		parser.parse(inputSource, handler);
	}

	/**
	 * Returns the launch manager
	 * 
	 * @return launch manager
	 */
	public static ILaunchManager getLaunchManager() {
		return DebugPlugin.getDefault().getLaunchManager();
	}

	/**
	 * Returns the 'AntUITests' project.
	 * 
	 * @return the test project
	 */
	public static IJavaProject getJavaProject() {
		return JavaCore.create(getProject());
	}

	/**
	 * Launches the given configuration and waits for the terminated event or the length of the given timeout, whichever comes first
	 * 
	 * @param config
	 * @param timeout
	 * @throws CoreException
	 */
	protected void launchAndTerminate(ILaunchConfiguration config, int timeout) throws CoreException {
		DebugEventWaiter waiter = new DebugElementKindEventWaiter(DebugEvent.TERMINATE, IProcess.class);
		waiter.setTimeout(timeout);

		Object terminatee = launchAndWait(config, waiter);
		assertTrue("terminatee is not an IProcess", terminatee instanceof IProcess); //$NON-NLS-1$
		IProcess process = (IProcess) terminatee;
		boolean terminated = process.isTerminated();
		assertTrue("process is not terminated", terminated); //$NON-NLS-1$
	}

	/**
	 * Launches the given configuration and waits for an event. Returns the source of the event. If the event is not received, the launch is
	 * terminated and an exception is thrown.
	 * 
	 * @param configuration
	 *            the configuration to launch
	 * @param waiter
	 *            the event waiter to use
	 * @return Object the source of the event
	 * @exception Exception
	 *                if the event is never received.
	 */
	protected Object launchAndWait(ILaunchConfiguration configuration, DebugEventWaiter waiter) throws CoreException {
		ILaunch launch = configuration.launch(ILaunchManager.RUN_MODE, null);
		Object suspendee = waiter.waitForEvent();
		if (suspendee == null) {
			try {
				launch.terminate();
			}
			catch (CoreException e) {
				e.printStackTrace();
			}
			throw new TestAgainException("Retest - Program did not suspend launching: " + configuration.getName()); //$NON-NLS-1$
		}
		boolean terminated = launch.isTerminated();
		assertTrue("launch did not terminate", terminated); //$NON-NLS-1$
		if (terminated && !ConsoleLineTracker.isClosed()) {
			ConsoleLineTracker.waitForConsole();
		}
		assertTrue("Console is not closed", ConsoleLineTracker.isClosed()); //$NON-NLS-1$
		return suspendee;
	}

	/**
	 * Returns the {@link IHyperlink} at the given offset on the given document, or <code>null</code> if there is no {@link IHyperlink} at that offset
	 * on the document.
	 * 
	 * @param offset
	 * @param doc
	 * @return the {@link IHyperlink} at the given offset on the given document or <code>null</code>
	 */
	protected IHyperlink getHyperlink(int offset, IDocument doc) {
		if (offset >= 0 && doc != null) {
			Position[] positions = null;
			try {
				positions = doc.getPositions(ConsoleHyperlinkPosition.HYPER_LINK_CATEGORY);
			}
			catch (BadPositionCategoryException ex) {
				// no links have been added
				return null;
			}
			for (int i = 0; i < positions.length; i++) {
				Position position = positions[i];
				if (offset >= position.getOffset() && offset <= (position.getOffset() + position.getLength())) {
					return ((ConsoleHyperlinkPosition) position).getHyperLink();
				}
			}
		}
		return null;
	}

	/**
	 * Returns the {@link Color} at the given offset on the given document, or <code>null</code> if there is no {@link Color} at that offset on the
	 * document.
	 * 
	 * @param offset
	 * @param doc
	 * @return the {@link Color} at the given offset on the given document or <code>null</code>
	 */
	protected Color getColorAtOffset(int offset, IDocument document) throws BadLocationException {
		if (document != null) {
			IDocumentPartitioner partitioner = document.getDocumentPartitioner();
			if (partitioner != null) {
				ITypedRegion[] regions = partitioner.computePartitioning(offset, document.getLineInformationOfOffset(offset).getLength());
				if (regions.length > 0) {
					IOConsolePartition partition = (IOConsolePartition) regions[0];
					return partition.getColor();
				}
			}
		}
		return null;
	}

	/**
	 * This is to help in increasing the test coverage by enabling access to fields and execution of methods irrespective of their Java language
	 * access permissions.
	 * 
	 * More accessor methods can be added to this on a need basis
	 */
	protected static abstract class TypeProxy {

		Object master = null;

		protected TypeProxy(Object obj) {
			master = obj;
		}

		/**
		 * Gets the method with the given method name and argument types.
		 * 
		 * @param methodName
		 *            the method name
		 * @param types
		 *            the argument types
		 * @return the method
		 */
		protected Method get(String methodName, Class<?>[] types) {
			Method method = null;
			try {
				method = master.getClass().getDeclaredMethod(methodName, types);
			}
			catch (SecurityException e) {
				fail();
			}
			catch (NoSuchMethodException ex) {
				fail();
			}
			Assert.isNotNull(method);
			method.setAccessible(true);
			return method;
		}

		/**
		 * Invokes the given method with the given arguments.
		 * 
		 * @param method
		 *            the given method
		 * @param arguments
		 *            the method arguments
		 * @return the method return value
		 */
		protected Object invoke(Method method, Object[] arguments) {
			try {
				return method.invoke(master, arguments);
			}
			catch (IllegalArgumentException e) {
				fail();
			}
			catch (InvocationTargetException e) {
				fail();
			}
			catch (IllegalAccessException e) {
				fail();
			}
			return null;
		}
	}
}