/*******************************************************************************
 * Copyright (c) 2018 Christian W. Damus and others.
 *
 * All rights reserved. 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:
 * Christian W. Damus - initial API and implementation
 ******************************************************************************/
package org.eclipse.emfforms.spi.editor;

import static java.util.Collections.singleton;
import static org.hamcrest.CoreMatchers.everyItem;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.change.ChangeDescription;
import org.eclipse.emf.ecore.change.ChangeFactory;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecp.ui.view.swt.reference.AttachmentStrategy;
import org.eclipse.emf.ecp.ui.view.swt.reference.EObjectSelectionStrategy;
import org.eclipse.emf.ecp.ui.view.swt.reference.OpenInNewContextStrategy;
import org.eclipse.emf.ecp.ui.view.swt.reference.ReferenceStrategy;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emfforms.bazaar.Bazaar;
import org.eclipse.emfforms.bazaar.BazaarContext;
import org.eclipse.emfforms.bazaar.Vendor;
import org.eclipse.emfforms.internal.editor.ecore.referenceservices.EcoreAttachmentStrategyProvider;
import org.eclipse.emfforms.internal.editor.ecore.referenceservices.EcoreEObjectSelectionStrategyProvider;
import org.eclipse.emfforms.internal.editor.ecore.referenceservices.EcoreOpenInNewContextStrategyProvider;
import org.eclipse.emfforms.internal.editor.ecore.referenceservices.EcoreReferenceStrategyProvider;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.Widget;
import org.hamcrest.CoreMatchers;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.osgi.framework.InvalidSyntaxException;

/**
 * Integration test cases for the Ecore Editor's reference service strategy provider classes.
 */
@SuppressWarnings({ "nls", "restriction" })
public class EcoreReferenceServiceCustomizationProviders_ITest {

	@Rule
	public final BazaarRule bazaar = new BazaarRule();

	private EPackage testPackage;

	/**
	 * Initializes me.
	 */
	public EcoreReferenceServiceCustomizationProviders_ITest() {
		super();
	}

	@ProviderType(EcoreReferenceStrategyProvider.class)
	@Test
	public void setEOppositeReference() throws InvalidSyntaxException {
		final EClass foo = (EClass) testPackage.getEClassifier("Foo");
		final EClass abstrakt = (EClass) testPackage.getEClassifier("Abstract");
		final EReference ref = (EReference) foo.getEStructuralFeature("ref");
		final EReference opposite = EcoreFactory.eINSTANCE.createEReference();
		abstrakt.getEStructuralFeatures().add(opposite);

		final ReferenceStrategy strategy = bazaar.getStrategy(foo, EcorePackage.Literals.EREFERENCE__EOPPOSITE);

		strategy.addElementsToReference(ref, EcorePackage.Literals.EREFERENCE__EOPPOSITE, singleton(opposite));

		assertThat("Reference's opposite not set", ref.getEOpposite(), is(opposite));
		assertThat("Opposite's opposite not set", opposite.getEOpposite(), is(ref));
		assertThat("Opposite's type not set", opposite.getEReferenceType(), is(foo));
		assertThat("Reference's type not set", ref.getEReferenceType(), is(abstrakt));
	}

	@ProviderType(EcoreAttachmentStrategyProvider.class)
	@Test
	public void attachOppositeReference() {
		final EClass foo = (EClass) testPackage.getEClassifier("Foo");
		final EClass abstrakt = (EClass) testPackage.getEClassifier("Abstract");
		final EReference ref = (EReference) foo.getEStructuralFeature("ref");
		ref.setEType(abstrakt);
		final EReference opposite = EcoreFactory.eINSTANCE.createEReference();

		final AttachmentStrategy strategy = bazaar.getStrategy(foo, EcorePackage.Literals.EREFERENCE__EOPPOSITE);

		strategy.addElementToModel(ref, EcorePackage.Literals.EREFERENCE__EOPPOSITE, opposite);

		assertThat("Opposite not added to its owner", opposite.getEContainingClass(), is(abstrakt));
		assertThat("Opposite's opposite not set", opposite.getEOpposite(), is(ref));
		assertThat("Opposite's type not set", opposite.getEReferenceType(), is(foo));
		assertThat("Opposite's name not set", opposite.getName(), notNullValue());
	}

	@ProviderType(EcoreEObjectSelectionStrategyProvider.class)
	@Test
	public void selectExistingEOpposite_refUntyped() {
		final EClass foo = (EClass) testPackage.getEClassifier("Foo");
		final EClass abstrakt = (EClass) testPackage.getEClassifier("Abstract");
		final EReference ref = (EReference) foo.getEStructuralFeature("ref");
		final EReference other = EcoreFactory.eINSTANCE.createEReference();
		other.setName("other");
		other.setEType(foo);
		foo.getEStructuralFeatures().add(other);
		final EReference opposite = EcoreFactory.eINSTANCE.createEReference();
		abstrakt.getEStructuralFeatures().add(opposite);

		final EObjectSelectionStrategy strategy = bazaar.getStrategy(foo, EcorePackage.Literals.EREFERENCE__EOPPOSITE);

		Collection<EObject> selection = everything();
		selection = strategy.collectExistingObjects(ref, EcorePackage.Literals.EREFERENCE__EOPPOSITE, selection);

		assertThat(selection, everyItem(CoreMatchers.<EObject> instanceOf(EReference.class)));
		assertThat(selection, hasItem(opposite));
		assertThat(selection, not(hasItem(ref)));
		assertThat(selection, hasItem(other)); // Could be an opposite, in theory
	}

	@ProviderType(EcoreEObjectSelectionStrategyProvider.class)
	@Test
	public void selectExistingEOpposite_refHasType() {
		final EClass foo = (EClass) testPackage.getEClassifier("Foo");
		final EClass abstrakt = (EClass) testPackage.getEClassifier("Abstract");
		final EReference ref = (EReference) foo.getEStructuralFeature("ref");
		final EReference other = EcoreFactory.eINSTANCE.createEReference();
		other.setName("other");
		other.setEType(foo);
		foo.getEStructuralFeatures().add(other);
		ref.setEType(abstrakt); // This determines the type that may contain opposites
		final EReference opposite = EcoreFactory.eINSTANCE.createEReference();
		abstrakt.getEStructuralFeatures().add(opposite);

		final EObjectSelectionStrategy strategy = bazaar.getStrategy(foo, EcorePackage.Literals.EREFERENCE__EOPPOSITE);

		Collection<EObject> selection = everything();
		selection = strategy.collectExistingObjects(ref, EcorePackage.Literals.EREFERENCE__EOPPOSITE, selection);

		assertThat(selection, everyItem(CoreMatchers.<EObject> instanceOf(EReference.class)));
		assertThat(selection, hasItem(opposite));
		assertThat(selection, not(hasItem(ref)));
		assertThat(selection, not(hasItem(other))); // Not in the ref's type
	}

	@ProviderType(EcoreEObjectSelectionStrategyProvider.class)
	@Test
	public void selectExistingSupertype() {
		final EClass foo = (EClass) testPackage.getEClassifier("Foo");
		final EClass abstrakt = (EClass) testPackage.getEClassifier("Abstract");
		final EClass subclass = EcoreFactory.eINSTANCE.createEClass();
		subclass.setName("Subtype");
		subclass.getESuperTypes().add(foo);
		testPackage.getEClassifiers().add(subclass);

		final EObjectSelectionStrategy strategy = bazaar.getStrategy(foo, EcorePackage.Literals.ECLASS__ESUPER_TYPES);

		Collection<EObject> selection = everything();
		selection = strategy.collectExistingObjects(foo, EcorePackage.Literals.ECLASS__ESUPER_TYPES, selection);

		assertThat(selection, everyItem(CoreMatchers.<EObject> instanceOf(EClass.class)));
		assertThat(selection, hasItem(abstrakt));
		assertThat(selection, not(hasItem(subclass))); // Would cause cycle
	}

	@ProviderType(EcoreEObjectSelectionStrategyProvider.class)
	@Test
	public void selectExistingAttributeType() {
		final EClass foo = (EClass) testPackage.getEClassifier("Foo");
		final EClassifier intType = testPackage.getEClassifier("int");
		final EStructuralFeature attr = foo.getEStructuralFeature("attr");

		final EObjectSelectionStrategy strategy = bazaar.getStrategy(attr, EcorePackage.Literals.ETYPED_ELEMENT__ETYPE);

		Collection<EObject> selection = everything();
		selection = strategy.collectExistingObjects(attr, EcorePackage.Literals.ETYPED_ELEMENT__ETYPE, selection);

		assertThat(selection, everyItem(CoreMatchers.<EObject> instanceOf(EDataType.class)));
		assertThat(selection, hasItem(intType));
	}

	@ProviderType(EcoreEObjectSelectionStrategyProvider.class)
	@Test
	public void selectExistingAnnotationReference() {
		final EClass foo = (EClass) testPackage.getEClassifier("Foo");
		final EClassifier intType = testPackage.getEClassifier("int");
		final EAnnotation annotation = EcoreFactory.eINSTANCE.createEAnnotation();
		annotation.setSource("test");
		foo.getEAnnotations().add(annotation);
		final EObjectSelectionStrategy strategy = bazaar.getStrategy(annotation,
			EcorePackage.Literals.EANNOTATION__REFERENCES);

		final ChangeDescription change = ChangeFactory.eINSTANCE.createChangeDescription();
		foo.eResource().getContents().add(change);

		Collection<EObject> selection = everything();
		Assume.assumeThat(selection, hasItem(change));
		selection = strategy.collectExistingObjects(annotation, EcorePackage.Literals.EANNOTATION__REFERENCES,
			selection);

		assertThat(selection, everyItem(CoreMatchers.<EObject> instanceOf(ENamedElement.class)));
		assertThat(selection, hasItem(intType));
		assertThat(selection, not(hasItem(change)));
	}

	@ProviderType(EcoreOpenInNewContextStrategyProvider.class)
	@Test
	public void openInNewContext() {
		final EClassifier foo = testPackage.getEClassifier("Foo");
		final OpenInNewContextStrategy strategy = bazaar.getStrategy(foo, foo.eContainmentFeature());
		assertThat(strategy, notNullValue());

		final Set<Shell> expectedShells = new HashSet<Shell>(Arrays.asList(Display.getCurrent().getShells()));

		// If a dialog appears close it
		final boolean[] doIt = { true };
		final boolean[] sawDialog = { false };
		Display.getDefault().asyncExec(new Runnable() {

			@Override
			public void run() {
				if (!doIt[0]) {
					return;
				}

				for (final Shell next : Display.getCurrent().getShells()) {
					if (!expectedShells.contains(next)) {
						sawDialog[0] = true;
						next.close();
					}
				}
			}
		});

		strategy.openInNewContext(foo.eContainer(), foo.eContainmentFeature(), foo);

		// If the dialog didn't appear, don't try anything after the test suite has moved on
		doIt[0] = false;

		assertThat("Open strategy presented a dialog", sawDialog[0], is(false));
	}

	//
	// Test framework
	//

	@Before
	public void createFixture() {
		final AdapterFactoryEditingDomain domain = new AdapterFactoryEditingDomain(
			new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE),
			new BasicCommandStack());

		testPackage = createTestPackage();
		createResource(domain.getResourceSet(), testPackage);
	}

	@After
	public void destroyFixture() {
		testPackage = null;
	}

	EPackage createTestPackage() {
		final EPackage result = createPackage("test");
		final EClass foo = EcoreFactory.eINSTANCE.createEClass();
		foo.setName("Foo");
		result.getEClassifiers().add(foo);
		final EAttribute state = EcoreFactory.eINSTANCE.createEAttribute();
		state.setName("attr");
		foo.getEStructuralFeatures().add(state);
		final EReference ref = EcoreFactory.eINSTANCE.createEReference();
		ref.setName("ref");
		foo.getEStructuralFeatures().add(ref);
		final EClass abstrakt = EcoreFactory.eINSTANCE.createEClass();
		abstrakt.setAbstract(true);
		abstrakt.setName("Abstract");
		result.getEClassifiers().add(abstrakt);
		final EDataType intType = EcoreFactory.eINSTANCE.createEDataType();
		intType.setName("int");
		intType.setInstanceTypeName("int");
		result.getEClassifiers().add(intType);
		return result;
	}

	void createResource(ResourceSet rset, EPackage ePackage) {
		final Resource resource = rset.createResource(URI.createURI(ePackage.getNsURI()).appendFileExtension("ecore"));
		resource.getContents().add(ePackage);
	}

	EPackage createPackage(String name) {
		final EPackage result = EcoreFactory.eINSTANCE.createEPackage();
		result.setName(name);
		result.setNsURI(String.format("http://test/%s.ecore", name));
		result.setNsPrefix(name);
		return result;
	}

	Collection<EObject> everything() {
		final Collection<EObject> result = new HashSet<EObject>();

		final ResourceSet rset = testPackage.eResource().getResourceSet();
		for (final Iterator<?> all = rset.getAllContents(); all.hasNext();) {
			final Object next = all.next();
			if (next instanceof EObject) {
				result.add((EObject) next);
			}
		}

		return result;
	}

	Runnable selectFirstElementInDialog(final boolean[] doIt) {
		return new Runnable() {

			@Override
			public void run() {
				if (doIt[0]) {
					Shell shell = Display.getCurrent().getActiveShell();
					if (shell == null) {
						final Shell[] all = Display.getCurrent().getShells();
						// Get the last opened
						if (all.length > 0) {
							shell = all[all.length - 1];
						}
					}
					if (shell != null) {
						selectFirstElement(shell);
						finishWizard(shell);
					}
				}
			}
		};
	}

	static void selectFirstElement(Shell shell) {
		Widget notify = null;
		Item selected = null;

		final Table table = findControl(shell, Table.class);
		if (table != null) {
			table.setSelection(0);
			notify = table;
			selected = table.getItem(0);
		} else {
			final Tree tree = findControl(shell, Tree.class);
			if (tree != null) {
				tree.setSelection(tree.getItem(0));
				notify = tree;
				selected = tree.getItem(0);
			} else {
				throw new IllegalStateException("no table nor tree to select");
			}
		}

		// Have to fire notification for JFace viewer to pick up
		final Event event = new Event();
		event.type = SWT.Selection;
		event.widget = notify;
		event.item = selected;
		notify.notifyListeners(SWT.Selection, event);
	}

	static <C extends Control> C findControl(Composite composite, Class<C> type) {
		C result = null;

		if (type.isInstance(composite)) {
			result = type.cast(composite);
		} else {
			for (final Control child : composite.getChildren()) {
				if (child instanceof Composite) {
					result = findControl((Composite) child, type);
				} else if (type.isInstance(child)) {
					result = type.cast(child);
				}

				if (result != null) {
					break;
				}
			}
		}

		return result;
	}

	static void finishWizard(Shell shell) {
		final Dialog dialog = (Dialog) shell.getData();

		try {
			final Method buttonPressed = Dialog.class.getDeclaredMethod("buttonPressed", int.class);
			buttonPressed.setAccessible(true);
			buttonPressed.invoke(dialog, IDialogConstants.FINISH_ID);
			// BEGIN COMPLEX CODE
		} catch (final Exception e) {
			// END COMPLEX CODE
			throw new RuntimeException(e);
		}
	}

	/**
	 * Annotates a test method with the strategy provider class to inject as
	 * a vendor in the {@linkplain BazaarRule bazaar fixture}.
	 */
	@Target(ElementType.METHOD)
	@Retention(RetentionPolicy.RUNTIME)
	@interface ProviderType {
		Class<? extends Vendor<?>> value();
	}

	/**
	 * A test rule that creates a bazaar with the single vendor specified by the
	 * test's {@link ProviderType} annotation.
	 */
	static class BazaarRule implements TestRule {
		private Bazaar<?> bazaar;

		@Override
		public Statement apply(final Statement base, final Description description) {
			return new Statement() {

				@Override
				public void evaluate() throws Throwable {
					starting(description);

					try {
						base.evaluate();
					} finally {
						finished(description);
					}
				}
			};
		}

		protected void starting(Description description) throws InstantiationException, IllegalAccessException {
			final Class<? extends Vendor<?>> strategyType = description
				.getAnnotation(ProviderType.class).value();

			final Vendor<?> provider = strategyType.newInstance();

			final Bazaar.Builder<?> builder = Bazaar.Builder.with(singleton(provider));
			bazaar = builder.build();
		}

		protected void finished(Description description) {
			bazaar = null;
		}

		<S> S getStrategy(EObject owner, EReference reference) {
			return getStrategy(owner, reference, null, null);
		}

		<S> S getStrategy(EObject owner, EReference reference, Object value) {
			return getStrategy(owner, reference, value == null ? null : value.getClass().getName(), value);
		}

		@SuppressWarnings("unchecked")
		<S> S getStrategy(EObject owner, EReference reference, String key,
			Object value) {
			final BazaarContext.Builder context = BazaarContext.Builder.empty();
			context.put(EObject.class, owner).put(EReference.class, reference);
			if (key != null) {
				context.put(key, value);
			}

			return (S) bazaar.createProduct(context.build());
		}
	}
}
