/*******************************************************************************
 * Copyright (c) 2006, 2016 Wind River Systems, Inc. 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:
 *     Markus Schorn - initial API and implementation
 *     Andrew Ferguson (Symbian)
 *     Sergey Prigogin (Google)
 *******************************************************************************/
package org.eclipse.cdt.core.testplugin.util;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ElementChangedEvent;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IElementChangedListener;
import org.eclipse.cdt.core.testplugin.ResourceHelper;
import org.eclipse.cdt.core.testplugin.TestScannerProvider;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
import org.eclipse.cdt.internal.core.pdom.CModelListener;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;

import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestFailure;
import junit.framework.TestResult;
import junit.framework.TestSuite;

public abstract class BaseTestCase extends TestCase {
	private static final String DEFAULT_INDEXER_TIMEOUT_SEC = "10";
	private static final String INDEXER_TIMEOUT_PROPERTY = "indexer.timeout";
	/**
	 * Indexer timeout used by tests. To avoid this timeout expiring during debugging add
	 * -Dindexer.timeout=some_large_number to VM arguments of the test launch configuration.
	 */
	protected static final int INDEXER_TIMEOUT_SEC = Integer
			.parseInt(System.getProperty(INDEXER_TIMEOUT_PROPERTY, DEFAULT_INDEXER_TIMEOUT_SEC));
	protected static final int INDEXER_TIMEOUT_MILLISEC = INDEXER_TIMEOUT_SEC * 1000;

	/**
	 * The GCC version to emulate when running tests.
	 * We emulate the latest version whose extensions we support.
	 */
	protected static final int GCC_MAJOR_VERSION_FOR_TESTS = 10;
	protected static final int GCC_MINOR_VERSION_FOR_TESTS = 1;

	/**
	 * This provides the systems new line separator. Use this if you do String comparisons in tests
	 * instead of hard coding '\n' or '\r\n' respectively.
	 */
	protected static final String NL = System.getProperty("line.separator");

	private boolean fExpectFailure;
	private int fBugNumber;
	private int fExpectedLoggedNonOK;
	private Deque<File> filesToDeleteOnTearDown = new ArrayDeque<>();

	public BaseTestCase() {
		super();
	}

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

	public static NullProgressMonitor npm() {
		return new NullProgressMonitor();
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		CPPASTNameBase.sAllowRecursionBindings = false;
		CPPASTNameBase.sAllowNameComputation = false;
		CModelListener.sSuppressUpdateOfLastRecentlyUsed = true;
	}

	@Override
	protected void tearDown() throws Exception {
		for (File file; (file = filesToDeleteOnTearDown.pollLast()) != null;) {
			file.delete();
		}
		ResourceHelper.cleanUp(getName());
		TestScannerProvider.clear();
		super.tearDown();
	}

	protected void deleteOnTearDown(File file) {
		filesToDeleteOnTearDown.add(file);
	}

	protected File createTempFile(String prefix, String suffix) throws IOException {
		File file = File.createTempFile(prefix, suffix);
		filesToDeleteOnTearDown.add(file);
		return file;
	}

	protected File nonExistentTempFile(String prefix, String suffix) {
		File file = new File(System.getProperty("java.io.tmpdir"), prefix + System.currentTimeMillis() + suffix);
		filesToDeleteOnTearDown.add(file);
		return file;
	}

	protected static TestSuite suite(Class clazz) {
		return suite(clazz, null);
	}

	protected static TestSuite suite(Class clazz, String failingTestPrefix) {
		TestSuite suite = new TestSuite(clazz);
		Test failing = getFailingTests(clazz, failingTestPrefix);
		if (failing != null) {
			suite.addTest(failing);
		}
		return suite;
	}

	private static Test getFailingTests(Class clazz, String prefix) {
		TestSuite suite = new TestSuite("Failing Tests");
		HashSet names = new HashSet();
		Class superClass = clazz;
		while (Test.class.isAssignableFrom(superClass) && !TestCase.class.equals(superClass)) {
			Method[] methods = superClass.getDeclaredMethods();
			for (Method method : methods) {
				addFailingMethod(suite, method, names, clazz, prefix);
			}
			superClass = superClass.getSuperclass();
		}
		if (suite.countTestCases() == 0) {
			return null;
		}
		return suite;
	}

	private static void addFailingMethod(TestSuite suite, Method m, Set names, Class clazz, String prefix) {
		String name = m.getName();
		if (!names.add(name)) {
			return;
		}
		if (name.startsWith("test") || (prefix != null && !name.startsWith(prefix))) {
			return;
		}
		if (name.equals("tearDown") || name.equals("setUp") || name.equals("runBare")) {
			return;
		}
		if (Modifier.isPublic(m.getModifiers())) {
			Class[] parameters = m.getParameterTypes();
			Class returnType = m.getReturnType();
			if (parameters.length == 0 && returnType.equals(Void.TYPE)) {
				Test test = TestSuite.createTest(clazz, name);
				((BaseTestCase) test).setExpectFailure(0);
				suite.addTest(test);
			}
		}
	}

	@Override
	public void runBare() throws Throwable {
		final List<IStatus> statusLog = Collections.synchronizedList(new ArrayList());
		ILogListener logListener = new ILogListener() {
			@Override
			public void logging(IStatus status, String plugin) {
				if (!status.isOK() && status.getSeverity() != IStatus.INFO) {
					switch (status.getCode()) {
					case IResourceStatus.NOT_FOUND_LOCAL:
					case IResourceStatus.NO_LOCATION_LOCAL:
					case IResourceStatus.FAILED_READ_LOCAL:
					case IResourceStatus.RESOURCE_NOT_LOCAL:
						// Logged by the resources plugin.
						return;
					}
					statusLog.add(status);
				}
			}
		};
		final CCorePlugin corePlugin = CCorePlugin.getDefault();
		if (corePlugin != null) { // Iff we don't run as a JUnit Plugin Test.
			corePlugin.getLog().addLogListener(logListener);
		}

		Throwable testThrowable = null;
		try {
			try {
				super.runBare();
			} catch (Throwable e) {
				testThrowable = e;
			}

			if (statusLog.size() != fExpectedLoggedNonOK) {
				StringBuilder msg = new StringBuilder("Expected number (").append(fExpectedLoggedNonOK).append(") of ");
				msg.append("Non-OK status objects in log differs from actual (").append(statusLog.size())
						.append(").\n");
				Throwable cause = null;
				if (!statusLog.isEmpty()) {
					synchronized (statusLog) {
						for (IStatus status : statusLog) {
							IStatus[] ss = { status };
							ss = status instanceof MultiStatus ? ((MultiStatus) status).getChildren() : ss;
							for (IStatus s : ss) {
								msg.append('\t').append(s.getMessage()).append(' ');

								Throwable t = s.getException();
								cause = cause != null ? cause : t;
								if (t != null) {
									msg.append(
											t.getMessage() != null ? t.getMessage() : t.getClass().getCanonicalName());
								}

								msg.append("\n");
							}
						}
					}
				}
				cause = cause != null ? cause : testThrowable;
				AssertionFailedError afe = new AssertionFailedError(msg.toString());
				afe.initCause(cause);
				throw afe;
			}
		} finally {
			if (corePlugin != null) {
				corePlugin.getLog().removeLogListener(logListener);
			}
		}

		if (testThrowable != null)
			throw testThrowable;
	}

	@Override
	public void run(TestResult result) {
		if (!fExpectFailure || Boolean.parseBoolean(System.getProperty("SHOW_EXPECTED_FAILURES"))) {
			super.run(result);
			return;
		}

		result.startTest(this);

		TestResult r = new TestResult();
		super.run(r);
		if (r.failureCount() == 1) {
			TestFailure failure = r.failures().nextElement();
			String msg = failure.exceptionMessage();
			if (msg != null && msg.startsWith("Method \"" + getName() + "\"")) {
				result.addFailure(this, new AssertionFailedError(msg));
			}
		} else if (r.errorCount() == 0 && r.failureCount() == 0) {
			String err = "Unexpected success of " + getName();
			if (fBugNumber > 0) {
				err += ", bug #" + fBugNumber;
			}
			result.addFailure(this, new AssertionFailedError(err));
		}

		result.endTest(this);
	}

	public void setExpectFailure(int bugNumber) {
		fExpectFailure = true;
		fBugNumber = bugNumber;
	}

	/**
	 * The last value passed to this method in the body of a testXXX method
	 * will be used to determine whether or not the presence of non-OK status objects
	 * in the log should fail the test. If the logged number of non-OK status objects
	 * differs from the last value passed, the test is failed. If this method is not called
	 * at all, the expected number defaults to zero.
	 * @param count the expected number of logged error and warning messages
	 */
	public void setExpectedNumberOfLoggedNonOKStatusObjects(int count) {
		fExpectedLoggedNonOK = count;
	}

	/**
	 * Some test steps need synchronizing against a CModel event. This class
	 * is a very basic means of doing that.
	 */
	static protected class ModelJoiner implements IElementChangedListener {
		private final boolean[] changed = new boolean[1];

		public ModelJoiner() {
			CoreModel.getDefault().addElementChangedListener(this);
		}

		public void clear() {
			synchronized (changed) {
				changed[0] = false;
				changed.notifyAll();
			}
		}

		public void join() throws CoreException {
			try {
				synchronized (changed) {
					while (!changed[0]) {
						changed.wait();
					}
				}
			} catch (InterruptedException e) {
				throw new CoreException(CCorePlugin.createStatus("Interrupted", e));
			}
		}

		public void dispose() {
			CoreModel.getDefault().removeElementChangedListener(this);
		}

		@Override
		public void elementChanged(ElementChangedEvent event) {
			// Only respond to post change events
			if (event.getType() != ElementChangedEvent.POST_CHANGE)
				return;

			synchronized (changed) {
				changed[0] = true;
				changed.notifyAll();
			}
		}
	}

	public static void waitForIndexer(ICProject project) throws InterruptedException {
		Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_REFRESH, null);
		assertTrue(CCoreInternals.getPDOMManager().joinIndexer(INDEXER_TIMEOUT_SEC * 1000, npm()));
	}

	public static void waitUntilFileIsIndexed(IIndex index, IFile file) throws Exception {
		TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
	}

	// Assertion helpers

	protected static <T> T assertInstance(Object o, Class<T> clazz, Class... cs) {
		assertNotNull("Expected object of " + clazz.getName() + " but got a null value", o);
		assertTrue("Expected " + clazz.getName() + " but got " + o.getClass().getName(), clazz.isInstance(o));
		for (Class c : cs) {
			assertNotNull("Expected object of " + c.getName() + " but got a null value", o);
			assertTrue("Expected " + c.getName() + " but got " + o.getClass().getName(), c.isInstance(o));
		}
		return clazz.cast(o);
	}

	protected static void assertValue(IValue value, long expectedValue) {
		assertNotNull(value);
		assertTrue(value.numberValue() instanceof Long);
		assertEquals(expectedValue, value.numberValue().longValue());
	}

	protected static void assertVariableValue(IVariable var, long expectedValue) {
		assertValue(var.getInitialValue(), expectedValue);
	}

	protected static String formatForPrinting(IASTName name) {
		String signature = name.getRawSignature();
		boolean saved = CPPASTNameBase.sAllowNameComputation;
		CPPASTNameBase.sAllowNameComputation = true;
		try {
			String nameStr = name.toString();
			if (signature.replace(" ", "").equals(nameStr.replace(" ", "")))
				return signature;
			return nameStr + " in " + signature;
		} catch (Throwable e) {
			return signature;
		} finally {
			CPPASTNameBase.sAllowNameComputation = saved;
		}
	}
}
