/*****************************************************************************
 * Copyright (c) 2013, 2017 CEA LIST, 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 v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   CEA LIST - Initial API and implementation
 *   Christian W. Damus - bug 460716
 *****************************************************************************/
package org.eclipse.papyrus.cdo.validation.problems.util.tests;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.junit.Assert.assertThat;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.emf.ecore.impl.EValidatorRegistryImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.papyrus.cdo.core.tests.AbstractPapyrusCDOTest;
import org.eclipse.papyrus.cdo.validation.problems.EProblem;
import org.eclipse.papyrus.cdo.validation.problems.ESeverity;
import org.eclipse.papyrus.cdo.validation.problems.ProblemsPackage;
import org.eclipse.papyrus.cdo.validation.problems.util.ProblemsManager;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.UMLFactory;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.resource.UMLResource;
import org.eclipse.uml2.uml.util.UMLValidator;
import org.junit.After;
import org.junit.Test;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;

/**
 * Tests suite for the {@link ProblemsManager} API.
 */
public class ProblemsManagerTest
		extends AbstractPapyrusCDOTest {

	private Set<ProblemsManager> managers = new java.util.HashSet<ProblemsManager>();

	@Test
	public void getProblemsAdapter() {
		CDOTransaction transaction = createTransaction();

		ProblemsManager mgr = getProblemsManager(transaction);

		// doesn't create a new instance
		assertThat(mgr,
				sameInstance(ProblemsManager.getProblemsManager(transaction
						.getResourceSet())));
	}

	@Test
	public void allProblems() {
		CDOTransaction transaction = createTransaction();
		CDOResource resource = transaction
				.createResource(getResourcePath("/resource1"));

		createTestModel(resource);
		final int expectedProblems = computeExpectedProblemsCount();

		ProblemsManager mgr = getProblemsManager(transaction);
		mgr.addDiagnostic(validate(resource));

		Collection<EProblem> allProblems = collect(mgr.getAllProblems());
		assertThat(allProblems.size(), equalTo(expectedProblems));
		assertIndistinguishableMembersProblem(resource, allProblems);
		assertGeneralCompatibilityProblem(resource, allProblems);
		assertUnownedElementProblem(resource, allProblems);
	}

	@Test
	public void allProblems_EObject_noCrossReferencer() {
		CDOTransaction transaction = createTransaction();
		CDOResource resource = transaction
				.createResource(getResourcePath("/resource1"));

		createTestModel(resource);
		final int expectedProblems = computeExpectedProblemsCount(getClass2());

		ProblemsManager mgr = getProblemsManager(transaction);
		mgr.addDiagnostic(validate(resource));

		Collection<EProblem> problems = collect(mgr
				.getAllProblems(getClass2(resource)));
		assertThat(problems.size(), equalTo(expectedProblems));
		assertIndistinguishableMembersProblem(resource, problems);
		assertGeneralCompatibilityProblem(resource, problems);
	}

	@Test
	public void allProblems_EObject_crossReferencer() {
		CDOTransaction transaction = createTransaction();
		CDOResource resource = transaction
				.createResource(getResourcePath("/resource1"));

		// attach a cross-reference adapter
		transaction.getResourceSet().eAdapters()
				.add(new ECrossReferenceAdapter());

		createTestModel(resource);
		final int expectedProblems = computeExpectedProblemsCount(getClass2());

		ProblemsManager mgr = getProblemsManager(transaction);
		mgr.addDiagnostic(validate(resource));

		Collection<EProblem> problems = collect(mgr
				.getAllProblems(getClass2(resource)));
		assertThat(problems.size(), equalTo(expectedProblems));
		assertIndistinguishableMembersProblem(resource, problems);
		assertGeneralCompatibilityProblem(resource, problems);
	}

	@Test
	public void purgeAll_noCrossReferencer() {
		CDOTransaction transaction = createTransaction();
		CDOResource resource = transaction
				.createResource(getResourcePath("/resource1"));

		createTestModel(resource);

		ProblemsManager mgr = getProblemsManager(transaction);
		mgr.addDiagnostic(validate(resource));

		mgr.purgeAllProblems();

		assertThat(mgr.getAllProblems().hasNext(), is(false));
	}

	@Test
	public void purgeAll_crossReferencer() {
		CDOTransaction transaction = createTransaction();
		CDOResource resource = transaction
				.createResource(getResourcePath("/resource1"));

		// attach a cross-reference adapter
		transaction.getResourceSet().eAdapters()
				.add(new ECrossReferenceAdapter());

		createTestModel(resource);

		ProblemsManager mgr = getProblemsManager(transaction);
		mgr.addDiagnostic(validate(resource));

		mgr.purgeAllProblems();

		assertThat(mgr.getAllProblems().hasNext(), is(false));
	}

	@Test
	public void purge_noCrossReferencer() {
		CDOTransaction transaction = createTransaction();
		CDOResource resource = transaction
				.createResource(getResourcePath("/resource1"));

		createTestModel(resource);
		final int expectedTotalProblems = computeExpectedProblemsCount();
		final int expectedClass3Problems = computeExpectedProblemsCount(getClass3());

		ProblemsManager mgr = getProblemsManager(transaction);
		mgr.addDiagnostic(validate(resource));

		mgr.purgeProblems(getClass3(resource));

		Collection<EProblem> problems = collect(mgr.getAllProblems());
		assertThat(problems.size(), equalTo(expectedTotalProblems - expectedClass3Problems));
		assertIndistinguishableMembersProblem(resource, problems);
		assertGeneralCompatibilityProblem(resource, problems);
	}

	@Test
	public void purge_crossReferencer() {
		CDOTransaction transaction = createTransaction();
		CDOResource resource = transaction
				.createResource(getResourcePath("/resource1"));

		// attach a cross-reference adapter
		transaction.getResourceSet().eAdapters()
				.add(new ECrossReferenceAdapter());

		createTestModel(resource);
		final int expectedTotalProblems = computeExpectedProblemsCount();
		final int expectedClass3Problems = computeExpectedProblemsCount(getClass3());

		ProblemsManager mgr = getProblemsManager(transaction);
		mgr.addDiagnostic(validate(resource));

		mgr.purgeProblems(getClass3(resource));

		Collection<EProblem> problems = collect(mgr.getAllProblems());
		assertThat(problems.size(), equalTo(expectedTotalProblems - expectedClass3Problems));
		assertIndistinguishableMembersProblem(resource, problems);
		assertGeneralCompatibilityProblem(resource, problems);
	}

	@Test
	public void disposeProblemsManager()
			throws Exception {

		CDOTransaction transaction = createTransaction();
		CDOResource resource = transaction
				.createResource(getResourcePath("/resource1"));

		// attach a cross-reference adapter
		ECrossReferenceAdapter xrefs = new ECrossReferenceAdapter();
		transaction.getResourceSet().eAdapters().add(xrefs);

		createTestModel(resource);

		ProblemsManager mgr = getProblemsManager(transaction);
		mgr.addDiagnostic(validate(resource));

		// gather weak references to the problems
		ReferenceQueue<EProblem> queue = new ReferenceQueue<EProblem>();
		List<Reference<EProblem>> references = new java.util.ArrayList<Reference<EProblem>>(
				3);
		for (Iterator<EProblem> iter = mgr.getAllProblems(); iter.hasNext();) {
			references.add(new WeakReference<EProblem>(iter.next(), queue));
		}

		mgr.dispose();

		// try to force GC
		for (int i = 0; i < 10; i++) {
			System.gc();
		}

		// assert that the problems are unreachable
		for (int i = 0; i < 3; i++) {
			Reference<? extends EProblem> ref = queue.remove(1000);
			assertThat(ref, notNullValue());
		}
	}

	@Test
	public void dispose_crossReferencerAddedAfter()
			throws Exception {

		CDOTransaction transaction = createTransaction();
		CDOResource resource = transaction
				.createResource(getResourcePath("/resource1"));

		createTestModel(resource);

		ProblemsManager mgr = getProblemsManager(transaction);
		mgr.addDiagnostic(validate(resource));

		// attach a cross-reference adapter *after* adding problems
		ECrossReferenceAdapter xrefs = new ECrossReferenceAdapter();
		transaction.getResourceSet().eAdapters().add(xrefs);

		// gather weak references to the problems
		ReferenceQueue<EProblem> queue = new ReferenceQueue<EProblem>();
		List<Reference<EProblem>> references = new java.util.ArrayList<Reference<EProblem>>(
				3);
		for (Iterator<EProblem> iter = mgr.getAllProblems(); iter.hasNext();) {
			references.add(new WeakReference<EProblem>(iter.next(), queue));
		}

		mgr.dispose();

		// try to force GC
		for (int i = 0; i < 10; i++) {
			System.gc();
		}

		// assert that the problems are unreachable
		for (int i = 0; i < 3; i++) {
			Reference<? extends EProblem> ref = queue.remove(1000);
			assertThat(ref, notNullValue());
		}
	}

	@Test
	public void customProblemClass() {
		CDOTransaction transaction = createTransaction();
		CDOResource resource = transaction
				.createResource(getResourcePath("/resource1"));

		createTestModel(resource);
		final int expectedProblems = computeExpectedProblemsCount();

		// not actually a different class, but a different way of creating it
		ProblemsManager mgr = ProblemsManager.createProblemsManager(
				transaction.getResourceSet(), ProblemsPackage.Literals.EPROBLEM);
		managers.add(mgr);
		mgr.addDiagnostic(validate(resource));

		Collection<EProblem> allProblems = collect(mgr.getAllProblems());
		assertThat(allProblems.size(), equalTo(expectedProblems));
		assertIndistinguishableMembersProblem(resource, allProblems);
		assertGeneralCompatibilityProblem(resource, allProblems);
		assertUnownedElementProblem(resource, allProblems);
	}

	//
	// Test framework
	//

	@After
	public void disposeProblemManagers()
			throws Exception {

		for (ProblemsManager next : managers) {
			next.dispose();
		}
	}

	void createTestModel(Resource res) {
		Model model = UMLFactory.eINSTANCE.createModel();
		model.setName("testmodel");
		res.getContents().add(model);

		Class class1 = model.createOwnedClass("Class1", false);

		Interface interface1 = model.createOwnedInterface("Interface1");

		Class class2 = model.createOwnedClass("Class2", false);
		class2.createGeneralization(interface1); // invalid generalization
		class2.createOwnedAttribute("attr1", class1);
		class2.createOwnedAttribute("attr1", class1); // indistinguishable

		Class class3 = UMLFactory.eINSTANCE.createClass();
		class3.setName("Class3");
		res.getContents().add(class3); // not owned
	}

	int computeExpectedProblemsCount() {
		int result;

		Resource resource = createScratchResource();

		try {
			Diagnostic diagnostic = validate(resource);
			result = diagnostic.getChildren().size();
		} finally {
			unload(resource);
		}

		return result;
	}

	int computeExpectedProblemsCount(Function<Resource, ? extends EObject> pertainingTo) {
		int result;

		Resource resource = createScratchResource();
		final EObject target = pertainingTo.apply(resource);

		try {
			Diagnostic diagnostic = validate(resource);
			result = Iterables.size(Iterables.filter(diagnostic.getChildren(), new Predicate<Diagnostic>() {
				@Override
				public boolean apply(Diagnostic input) {
					List<?> data = input.getData();
					return (data != null) && !data.isEmpty() && (data.get(0) == target);
				}
			}));
		} finally {
			unload(resource);
		}

		return result;
	}

	Resource createScratchResource() {
		Resource result = UMLResource.Factory.INSTANCE.createResource(URI.createURI("bogus://scratch.uml"));
		createTestModel(result);
		return result;
	}

	void unload(Resource resource) {
		resource.unload();
		if (resource.getResourceSet() != null) {
			resource.getResourceSet().getResources().remove(resource);
		}
		resource.eAdapters().clear();
	}

	Model getModel(Resource resource) {
		return (Model) EcoreUtil.getObjectByType(resource.getContents(),
				UMLPackage.Literals.MODEL);
	}

	Class getClass1(Resource resource) {
		return getClass1().apply(resource);
	}

	Function<Resource, Class> getClass1() {
		return getNamedClass("Class1");
	}

	Function<Resource, Class> getNamedClass(final String name) {
		return new Function<Resource, Class>() {
			@Override
			public Class apply(Resource input) {
				return (Class) getModel(input).getOwnedType(name);
			}
		};
	}

	Class getClass2(Resource resource) {
		return getClass2().apply(resource);
	}

	Function<Resource, Class> getClass2() {
		return getNamedClass("Class2");
	}

	Class getClass3(Resource resource) {
		return getClass3().apply(resource);
	}

	Function<Resource, Class> getClass3() {
		return getRoot(Class.class);
	}

	<T extends EObject> Function<Resource, T> getRoot(final java.lang.Class<T> metaclass) {
		return new Function<Resource, T>() {
			@Override
			public T apply(Resource input) {
				return Iterables.getFirst(Iterables.filter(input.getContents(), metaclass), null);
			}
		};
	}

	Interface getInterface1(Resource resource) {
		return (Interface) getModel(resource).getOwnedType("Interface1");
	}

	ProblemsManager getProblemsManager(CDOView view) {
		return getProblemsManager(view.getResourceSet());
	}

	ProblemsManager getProblemsManager(ResourceSet resourceSet) {
		ProblemsManager result = ProblemsManager
				.getProblemsManager(resourceSet);
		managers.add(result);
		return result;
	}

	Diagnostic validate(Resource resource) {
		EValidator.Registry registry = new EValidatorRegistryImpl(
				EValidator.Registry.INSTANCE);
		registry.put(UMLPackage.eINSTANCE, new UMLValidator());

		BasicDiagnostic result = new BasicDiagnostic();
		Diagnostician diagnostician = new Diagnostician(registry);

		for (EObject next : resource.getContents()) {
			diagnostician.validate(next, result);
		}

		return result;
	}

	Collection<EProblem> collect(Iterator<? extends EProblem> problems) {
		Collection<EProblem> result = new java.util.ArrayList<EProblem>();

		while (problems.hasNext()) {
			result.add(problems.next());
		}

		return result;
	}

	void assertProblem(Collection<EProblem> problems, ESeverity severity,
			String source, int code, String messagePattern, EObject element,
			EObject... related) {

		final List<EObject> relatedList = Arrays.asList(related);
		final Pattern pattern = Pattern.compile(messagePattern);

		EProblem found = null;
		for (EProblem problem : problems) {
			if (problem.getElement() == element //
					&& problem.getRelated().equals(relatedList) //
					&& problem.getSeverity() == severity //
					&& pattern.matcher(problem.getMessage()).find() //
					&& source.equals(problem.getSource()) //
					&& problem.getCode() == code) {
				found = problem;
				break;
			}
		}

		assertThat(found, notNullValue());
	}

	void assertIndistinguishableMembersProblem(Resource resource,
			Collection<EProblem> problems) {

		Class class2 = getClass2(resource);

		assertProblem(problems, ESeverity.WARNING,
				UMLValidator.DIAGNOSTIC_SOURCE,
				UMLValidator.NAMESPACE__MEMBERS_DISTINGUISHABLE, "disting", class2);
	}

	void assertGeneralCompatibilityProblem(Resource resource,
			Collection<EProblem> problems) {

		Class class2 = getClass2(resource);
		Interface interface1 = getInterface1(resource);

		assertProblem(problems, ESeverity.WARNING,
				UMLValidator.DIAGNOSTIC_SOURCE,
				UMLValidator.CLASSIFIER__SPECIALIZE_TYPE, "special", class2,
				interface1);
	}

	void assertUnownedElementProblem(Resource resource,
			Collection<EProblem> problems) {

		Class class3 = getClass3(resource);

		assertProblem(problems, ESeverity.WARNING,
				UMLValidator.DIAGNOSTIC_SOURCE, UMLValidator.ELEMENT__HAS_OWNER,
				"owned", class3);
	}
}
