/*******************************************************************************
 * Copyright (c) 2009, 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
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 474274
 ******************************************************************************/

package org.eclipse.e4.core.internal.tests.contexts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.e4.core.contexts.ContextFunction;
import org.eclipse.e4.core.contexts.EclipseContextFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.contexts.RunAndTrack;
import org.eclipse.e4.core.internal.tests.CoreTestsActivator;
import org.junit.After;
import org.junit.Test;

/**
 * Tests for {@link org.eclipse.e4.core.RunAndTrack.context.IRunAndTrack}.
 */
public class RunAndTrackTest {

	private static final class TestRAT extends RunAndTrack {


		private String varName;
		private Object varValue;
		private int calls = 0;

		public TestRAT(String varName) {
			this.varName = varName;
		}

		@Override
		public boolean changed(IEclipseContext context) {
			++calls;
			varValue = context.get(varName);
			return true;
		}

		public int getCalls() {
			return calls;
		}

		public Object getVarValue() {
			return varValue;
		}

		public void resetCalls() {
			calls = 0;
		}

	}

	private class ActivePartLookupFunction extends ContextFunction {

		@Override
		public Object compute(IEclipseContext context, String contextKey) {
			IEclipseContext childContext = (IEclipseContext) context.getLocal(ACTIVE_CHILD);
			if (childContext != null) {
				return childContext.get(ACTIVE_PART);
			}
			return context.get(INTERNAL_LOCAL_PART);
		}

	}

	static final String ACTIVE_CHILD = "activeChild";

	static final String ACTIVE_PART = "activePart";

	static final String ACTIVE_PART_ID = "activePartId";

	static final String INTERNAL_LOCAL_PART = "localPart";

	private List<IEclipseContext> createdContexts = new ArrayList<>();

	private IEclipseContext createContext(IEclipseContext parentContext, String level) {
		IEclipseContext childContext = parentContext.createChild(level);
		createdContexts.add(childContext);
		return childContext;
	}

	private IEclipseContext getGlobalContext() {
		IEclipseContext serviceContext = EclipseContextFactory
				.getServiceContext(CoreTestsActivator.getDefault().getBundleContext());
		// global initialization and setup, usually done by workbench
		IEclipseContext appContext = createContext(serviceContext, "globalContext");

		appContext.set("globalContext", appContext);

		return appContext;
	}

	private IEclipseContext[] createNextLevel(IEclipseContext parent, String prefix, int num) {
		assertTrue(num > 0);
		IEclipseContext[] contexts = new IEclipseContext[num];
		for (int i = 0; i < num; i++) {
			contexts[i] = createContext(parent, prefix + i);
			contexts[i].set(INTERNAL_LOCAL_PART, prefix + i);
		}
		parent.set(ACTIVE_CHILD, contexts[0]);
		return contexts;
	}

	@After
	public void tearDown() throws Exception {
		for (IEclipseContext context : createdContexts) {
			context.dispose();
		}
		createdContexts.clear();
	}

	@Test
	public void testActiveChain() throws Exception {
		final IEclipseContext workbenchContext = getGlobalContext();
		workbenchContext.set("activePart", new ActivePartLookupFunction());
		final IEclipseContext[] windows = createNextLevel(workbenchContext, "window", 1);
		createNextLevel(windows[0], "part", 2);
		assertEquals("part0", workbenchContext.get(ACTIVE_PART));
	}

	@Test
	public void testActiveChange() throws Exception {
		final IEclipseContext workbenchContext = getGlobalContext();
		workbenchContext.set("activePart", new ActivePartLookupFunction());
		final IEclipseContext[] windows = createNextLevel(workbenchContext, "window", 1);
		final IEclipseContext[] parts = createNextLevel(windows[0], "part", 2);
		assertEquals("part0", workbenchContext.get(ACTIVE_PART));

		windows[0].set(ACTIVE_CHILD, parts[1]);
		assertEquals("part1", workbenchContext.get(ACTIVE_PART));
	}

	/**
	 * There was a failing scenario in the legacy workbench support. This captures the hierarchy and
	 * function (without any workbench level references). It should be updated when we figure out
	 * the failing scenario :-)
	 *
	 * @throws Exception
	 */
	@Test
	public void testRunAndTrackComplex() throws Exception {
		final IEclipseContext workbenchContext = getGlobalContext();
		workbenchContext.set("activePart", new ActivePartLookupFunction());
		final IEclipseContext[] windows = createNextLevel(workbenchContext, "window", 1);
		windows[0].runAndTrack(new RunAndTrack() {
			@Override
			public boolean changed(IEclipseContext context) {
				final Object part = windows[0].get(ACTIVE_PART);
				windows[0].set(ACTIVE_PART_ID, part);
				return true;
			}

			@Override
			public String toString() {
				return ACTIVE_PART_ID;
			}
		});

		final IEclipseContext[] mainSashes = createNextLevel(windows[0], "mainSash", 2);
		createNextLevel(mainSashes[1], "editorArea", 1);
		final IEclipseContext[] viewSashes = createNextLevel(mainSashes[0], "viewSashes", 2);

		// create package explorer stack
		final IEclipseContext[] packageStack = createNextLevel(viewSashes[0], "packageStack", 1);
		final IEclipseContext[] packageViews = createNextLevel(packageStack[0], "packageViews", 3);
		assertNotNull(packageViews);
		assertEquals("packageViews0", windows[0].get(ACTIVE_PART));
		assertEquals("packageViews0", windows[0].get(ACTIVE_PART_ID));

		// create problems stack
		final IEclipseContext[] problemsStack = createNextLevel(viewSashes[1], "problemsStack", 1);
		final IEclipseContext[] problemsViews = createNextLevel(problemsStack[0], "problemViews", 5);
		assertNotNull(problemsViews);
		assertEquals("packageViews0", windows[0].get(ACTIVE_PART));
		assertEquals("packageViews0", windows[0].get(ACTIVE_PART_ID));

		assertEquals("problemViews0", problemsStack[0].get(ACTIVE_PART));
		// this won't change since it is a "runAndTrack" at the window context
		// level
		assertEquals("packageViews0", problemsStack[0].get(ACTIVE_PART_ID));

		// set the "problems view" active, propagating the information up
		// the active chain.
		problemsStack[0].set(ACTIVE_CHILD, problemsViews[0]);
		viewSashes[1].set(ACTIVE_CHILD, problemsStack[0]);
		mainSashes[0].set(ACTIVE_CHILD, viewSashes[1]);
		windows[0].set(ACTIVE_CHILD, mainSashes[0]);
		workbenchContext.set(ACTIVE_CHILD, windows[0]);

		assertEquals("problemViews0", windows[0].get(ACTIVE_PART));
		assertEquals("problemViews0", windows[0].get(ACTIVE_PART_ID));

		assertEquals("packageViews0", packageStack[0].get(ACTIVE_PART));
		assertEquals("problemViews0", packageStack[0].get(ACTIVE_PART_ID));
	}

	@Test
	public void testRunAndTrackSimple() throws Exception {
		final IEclipseContext workbenchContext = getGlobalContext();
		workbenchContext.set("activePart", new ActivePartLookupFunction());
		final IEclipseContext[] windows = createNextLevel(workbenchContext, "window", 1);
		windows[0].runAndTrack(new RunAndTrack() {
			@Override
			public boolean changed(IEclipseContext context) {
				final Object part = windows[0].get(ACTIVE_PART);
				windows[0].set(ACTIVE_PART_ID, part);
				return true;
			}

			@Override
			public String toString() {
				return ACTIVE_PART_ID;
			}
		});

		final IEclipseContext[] parts = createNextLevel(windows[0], "part", 2);
		assertEquals("part0", workbenchContext.get(ACTIVE_PART));
		assertEquals("part0", windows[0].get(ACTIVE_PART_ID));

		windows[0].set(ACTIVE_CHILD, parts[1]);
		assertEquals("part1", windows[0].get(ACTIVE_PART));
		assertEquals("part1", windows[0].get(ACTIVE_PART_ID));
	}

	/**
	 * Test how a RAT responds to a change hidden from it; changed value is == to child value
	 */
	@Test
	public void testSetHiddenValueToChildObject() {
		final String newRootValue = "child";

		doHiddenValueChangeTest(newRootValue);
	}

	/**
	 * Test how a RAT responds to a change hidden from it; changed value is != to child value
	 */
	@Test
	public void testSetHiddenValueToDifferentObject() {
		final String newRootValue = "other";

		doHiddenValueChangeTest(newRootValue);
	}

	/**
	 * Test how a RAT responds to a change hidden from it; changed value is != to child value (but is .equals())
	 */
	@Test
	public void testSetHiddenValueToObjectEqualToChild() {
		// avoid compiler's pushing all my strings into a single string pool
		final String newRootValue = new String("child");

		doHiddenValueChangeTest(newRootValue);
	}

	/**
	 * Test how a RAT responds to a change hidden from it; changed value is == to root value
	 */
	@Test
	public void testSetHiddenValueToRootObject() {
		final String newRootValue = "root";

		doHiddenValueChangeTest(newRootValue);
	}

	/**
	 * Test how a RAT responds to a change hidden from it; changed value is != to root value (but is .equals())
	 */
	@Test
	public void testSetHiddenValueToEqualRootObject() {
		// avoid compiler's pushing all my strings into a single string pool
		final String newRootValue = new String("root");

		doHiddenValueChangeTest(newRootValue);
	}

	/**
	 * Test how a RAT responds to a change hidden from it; changed value is == to root value
	 */
	@Test
	public void testSetHiddenValueToNull() {
		final String newRootValue = null;

		doHiddenValueChangeTest(newRootValue);
	}

	/**
	 * Perform a hidden value test that verifies that the test RAT does not run, and
	 * that has last seen the initial value in the child context (namely "child").
	 * @param newRootValue the new value for the variable 'v' in the root context.
	 * @see #doHiddenValueChangeTest(ITestAction, Object, int)
	 */
	void doHiddenValueChangeTest(final String newRootValue) {
		doHiddenValueChangeTest((IEclipseContext root, String var) -> {
			root.set(var, newRootValue);
		}, "child", 0);
	}

	/**
	 * Interface defining function
	 *
	 */
	private interface ITestAction {

		void execute(IEclipseContext root, String var);

	}
	/**
	 * Create a two level hierarchy of contexts, each defining a variable 'v' with values 'root' and 'child', respectively.
	 * Create and install a RAT on the child context that is dependent on 'v'.
	 * Run <code>testAction</code>.
	 * Tests whether the RAT ran the expected number of times,
	 * and tests last value of 'v' that the RAT saw.
	 * @param testAction the context action to perform as part of the test
	 * @param expectedValue the expected last value of variable 'v' that the RAT saw.
	 * @param expectedRATCalls the expected number of times the RAT was run in response to testAction
	 */
	void doHiddenValueChangeTest(ITestAction testAction, Object expectedValue, int expectedRATCalls) {
		final IEclipseContext root = getGlobalContext();
		final IEclipseContext child = root.createChild("child");

		root.set("v", "root");
		child.set("v", "child");
		final TestRAT testRAT = new TestRAT("v");

		// install the RAT
		child.runAndTrack(testRAT);
		assertEquals("child", testRAT.getVarValue());
		assertEquals(1, testRAT.getCalls());

		testRAT.resetCalls();
		// set the new root value
		testAction.execute(root, "v");
		assertEquals(expectedValue, testRAT.getVarValue());
		assertEquals(expectedRATCalls, testRAT.getCalls());
	}

	/**
	 * Test that a variable change in a context hidden from a RAT in
	 * a child context does not re-run the RAT.
	 */
	@Test
	public void testRemoveHiddenVariable() {
		doHiddenValueChangeTest((IEclipseContext root, String var) -> {
			root.remove(var);
		}, "child", 0);
	}

	/**
	 * Test that setting a context variable to it's existing
	 * value does not re-run dependent RATs
	 */
	@Test
	public void testSetContextVarToSameObject() {
		doSingleContextChangeTest((IEclipseContext root, String var) -> {
			root.set(var, "root");
		}, "root", 0);
	}

	/**
	 * Test that setting a context variable to a value that {@link Object#equals(Object) equals}
	 * the current value, but is same object DOES re-run dependent RATs.
	 */
	@Test
	public void testSetContextVarToEqualObject() {
		doSingleContextChangeTest((IEclipseContext root, String var) -> {
			root.set(var, new String("root"));
		}, "root", 1);
	}

	/**
	 * Test that setting a context variable to a different object, not equal to the
	 * current value re-runs dependent RATs.
	 */
	@Test
	public void testSetContextVarToOtherObject() {
		doSingleContextChangeTest((IEclipseContext root, String var) -> {
			root.set(var, "other");
		}, "other", 1);
	}

	/**
	 * Test that removing a context variable re-runs dependent RATs.
	 */
	@Test
	public void testRemoveContextVar() {
		doSingleContextChangeTest((root, var) -> root.remove(var), null, 1);

	}

	/**
	 * Creates a context, sets a variable 'v' to "root", creates a RAT dependent on 'v' in the context,
	 * then executes <code>testAction</code> and tests whether the RAT ran the expected number of times,
	 * and tests last value of 'v' that the RAT saw.
	 * @param testAction the context action to perform as part of the test
	 * @param expectedValue the expected last value of variable 'v' that the RAT saw.
	 * @param expectedRATCalls the expected number of times the RAT was run in response to testAction
	 */
	private void doSingleContextChangeTest(ITestAction testAction, Object expectedValue, int expectedRATCalls) {
		final IEclipseContext root = getGlobalContext();

		root.set("v", "root");

		final TestRAT testRAT = new TestRAT("v");
		// install the RAT
		root.runAndTrack(testRAT);
		assertEquals("root", testRAT.getVarValue());
		assertEquals(1, testRAT.getCalls());

		testRAT.resetCalls();
		testAction.execute(root, "v");
		assertEquals(expectedRATCalls, testRAT.getCalls());
		assertEquals(expectedValue, testRAT.getVarValue());

	}
}
