/*******************************************************************************
 * Copyright (c) 2011-2019 EclipseSource Muenchen GmbH 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:
 * Stefan Dirix - initial API and implementation
 * Christian W. Damus - bugs 533522, 552127
 ******************************************************************************/
package org.eclipse.emf.ecp.view.validation.test;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecp.common.spi.UniqueSetting;
import org.eclipse.emf.ecp.test.common.DefaultRealm;
import org.eclipse.emf.ecp.view.internal.context.ViewModelContextImpl;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContextFactory;
import org.eclipse.emf.ecp.view.spi.model.VControl;
import org.eclipse.emf.ecp.view.spi.model.VFeaturePathDomainModelReference;
import org.eclipse.emf.ecp.view.spi.model.VView;
import org.eclipse.emf.ecp.view.spi.model.VViewFactory;
import org.eclipse.emf.ecp.view.spi.validation.ValidationProvider;
import org.eclipse.emf.ecp.view.spi.validation.ValidationService;
import org.eclipse.emf.ecp.view.spi.validation.ViewValidationListener;
import org.eclipse.emf.ecp.view.validation.test.model.CrossReferenceContainer;
import org.eclipse.emf.ecp.view.validation.test.model.CrossReferenceContent;
import org.eclipse.emf.ecp.view.validation.test.model.TableContentWithInnerChild;
import org.eclipse.emf.ecp.view.validation.test.model.TestFactory;
import org.eclipse.emf.ecp.view.validation.test.model.TestPackage;
import org.eclipse.emfforms.spi.common.report.AbstractReport;
import org.eclipse.emfforms.spi.common.report.ReportService;
import org.eclipse.emfforms.spi.common.report.ReportServiceConsumer;
import org.eclipse.emfforms.spi.core.services.mappingprovider.EMFFormsMappingProviderManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;

/**
 * @author Stefan Dirix
 *
 */
@SuppressWarnings("restriction")
public class ValidationService_PTest {

	private DefaultRealm defaultRealm;

	private VControl control;
	private ValidationService validationService;

	private CrossReferenceContainer container;
	private CrossReferenceContent content;

	private CrossReferenceContainer otherContainer;

	private BundleContext bundleContext;

	private ServiceReference<ReportService> reportServiceReference;

	private ReportService reportService;

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		defaultRealm = new DefaultRealm();

		bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
		reportServiceReference = bundleContext.getServiceReference(ReportService.class);
		reportService = bundleContext.getService(reportServiceReference);
	}

	/**
	 * @throws java.lang.Exception
	 */
	@After
	public void tearDown() throws Exception {
		defaultRealm.dispose();
		bundleContext.ungetService(reportServiceReference);
	}

	private void setupContent() {
		final VView view = VViewFactory.eINSTANCE.createView();
		view.setRootEClass(TestPackage.eINSTANCE.getContent());

		control = VViewFactory.eINSTANCE.createControl();

		final VFeaturePathDomainModelReference domainModelReference = VViewFactory.eINSTANCE
			.createFeaturePathDomainModelReference();
		domainModelReference.setDomainModelEFeature(TestPackage.eINSTANCE.getCrossReferenceContent_Parent());
		control.setDomainModelReference(domainModelReference);

		view.getChildren().add(control);

		container = TestFactory.eINSTANCE.createCrossReferenceContainer();
		otherContainer = TestFactory.eINSTANCE.createCrossReferenceContainer();
		content = TestFactory.eINSTANCE.createCrossReferenceContent();
		final ViewModelContext vmc = ViewModelContextFactory.INSTANCE.createViewModelContext(view, content);
		validationService = vmc.getService(ValidationService.class);
	}

	/**
	 * There should be no validation on an unset crossreferenced element.
	 */
	@Test
	public void testNoValidationOnUnsetElements() {
		setupContent();
		container.setSingleContent(content);
		final List<Boolean> called = new ArrayList<Boolean>(1);
		called.add(false);
		validationService.addValidationProvider(new ValidationProvider() {
			@Override
			public List<Diagnostic> validate(EObject eObject) {
				if (content == eObject) {
					called.set(0, true);
				}
				return Collections.emptyList();
			}
		});
		called.set(0, false);
		container.setSingleContent(null);

		assertFalse(called.get(0));
	}

	/**
	 * There should be a validation on a set crossreferenced element.
	 */
	@Test
	public void testValidationOnSetElements() {
		setupContent();
		container.setSingleContent(content);
		final List<Boolean> called = new ArrayList<Boolean>(1);
		called.add(false);
		validationService.addValidationProvider(new ValidationProvider() {
			@Override
			public List<Diagnostic> validate(EObject eObject) {
				if (content == eObject) {
					called.set(0, true);
				}
				return Collections.emptyList();
			}
		});
		called.set(0, false);
		otherContainer.setSingleContent(content);

		assertTrue(called.get(0));
	}

	/**
	 * There should be no validation on a removed crossreferenced element.
	 */
	@Test
	public void testNoValidationOnRemovedElements() {
		setupContent();
		container.getContents().add(content);

		final List<Boolean> called = new ArrayList<Boolean>(1);
		called.add(false);
		validationService.addValidationProvider(new ValidationProvider() {
			@Override
			public List<Diagnostic> validate(EObject eObject) {
				if (content == eObject) {
					called.set(0, true);
				}
				return Collections.emptyList();
			}
		});
		called.set(0, false);
		container.getContents().remove(content);

		assertFalse(called.get(0));
	}

	/**
	 * There should be a validation on a moved crossreferenced element.
	 */
	@Test
	public void testValidationOnMovedElements() {
		setupContent();
		container.getContents().add(content);

		final List<Boolean> called = new ArrayList<Boolean>(1);
		called.add(false);
		validationService.addValidationProvider(new ValidationProvider() {
			@Override
			public List<Diagnostic> validate(EObject eObject) {
				if (content == eObject) {
					called.set(0, true);
				}
				return Collections.emptyList();
			}
		});
		called.set(0, false);
		otherContainer.getContents().add(content);

		assertTrue(called.get(0));
	}

	@Test
	public void testValidationTimeoutReport2000() {
		setupContent();
		container.getContents().add(content);

		final List<Boolean> called = new ArrayList<Boolean>(1);
		called.add(false);
		final ReportServiceConsumer reportServiceConsumer = new ReportServiceConsumer() {

			@Override
			public void reported(AbstractReport reportEntity) {
				assertTrue(reportEntity.getMessage().startsWith("Validation took longer than expected for"));
				called.set(0, true);
			}
		};
		reportService.addConsumer(reportServiceConsumer);
		validationService.addValidationProvider(new ValidationProvider() {
			@Override
			public List<Diagnostic> validate(EObject eObject) {
				try {
					Thread.sleep(3000);
				} catch (final InterruptedException ex) {
				}
				return Collections.emptyList();
			}
		});

		validationService.validate(Arrays.asList(content.eContainer()));
		assertTrue("Validation report missing", called.get(0));
		reportService.removeConsumer(reportServiceConsumer);
	}

	@Test
	public void testValidationTimeoutReport1000() {
		setupContent();
		container.getContents().add(content);

		final List<Boolean> called = new ArrayList<Boolean>(1);
		called.add(false);
		final ReportServiceConsumer reportServiceConsumer = new ReportServiceConsumer() {

			@Override
			public void reported(AbstractReport reportEntity) {
				assertTrue("Real Message:" + reportEntity.getMessage(),
					reportEntity.getMessage().startsWith("Validation took longer than expected for"));
				called.set(0, true);

			}
		};
		reportService.addConsumer(reportServiceConsumer);
		validationService.addValidationProvider(new ValidationProvider() {
			@Override
			public List<Diagnostic> validate(EObject eObject) {
				try {
					Thread.sleep(2000);
				} catch (final InterruptedException ex) {
				}
				return Collections.emptyList();
			}
		});

		validationService.validate(Arrays.asList(content.eContainer()));
		assertTrue("Validation report missing", called.get(0));
		reportService.removeConsumer(reportServiceConsumer);
	}

	@Test
	public void testValidationTimeoutReportNoDelay() {
		setupContent();
		container.getContents().add(content);

		final List<Boolean> called = new ArrayList<Boolean>(1);
		called.add(false);
		final ReportServiceConsumer reportServiceConsumer = new ReportServiceConsumer() {

			@Override
			public void reported(AbstractReport reportEntity) {
				assertTrue(reportEntity.getMessage().startsWith("Validation took longer than expected for"));
				called.set(0, true);

			}
		};
		reportService.addConsumer(reportServiceConsumer);
		validationService.addValidationProvider(new ValidationProvider() {
			@Override
			public List<Diagnostic> validate(EObject eObject) {
				return Collections.emptyList();
			}
		});

		validationService.validate(Arrays.asList(content.eContainer()));
		assertFalse("Validation report present", called.get(0));

		reportService.removeConsumer(reportServiceConsumer);
	}

	@Test
	public void testViewModelChangeListenerCutOffDMR() {
		/* setup domain */
		final TableContentWithInnerChild parent = TestFactory.eINSTANCE.createTableContentWithInnerChild();
		final TableContentWithInnerChild middle = TestFactory.eINSTANCE.createTableContentWithInnerChild();
		final TableContentWithInnerChild child = TestFactory.eINSTANCE.createTableContentWithInnerChild();
		parent.setInnerChild(middle);
		middle.setInnerChild(child);

		/* setup view */
		final VView view = VViewFactory.eINSTANCE.createView();

		final VControl vControl = VViewFactory.eINSTANCE.createControl();
		view.getChildren().add(vControl);
		vControl.setDomainModelReference(
			TestPackage.eINSTANCE.getTableContentWithInnerChild_Stuff(),
			Arrays.asList(
				TestPackage.eINSTANCE.getTableContentWithInnerChild_InnerChild(),
				TestPackage.eINSTANCE.getTableContentWithInnerChild_InnerChild()));

		/* setup rendering */
		ViewModelContextFactory.INSTANCE.createViewModelContext(view, parent);

		/* act */
		parent.setInnerChild(null); /* cut off */
		vControl.setEnabled(false); /* produce view notifications */
		vControl.setEnabled(true);/* produce view notifications */

		/* assert */
		/* cutting of should not produce NPEs as this is legit */
	}

	@Test
	public void testBug529403controlAdded() {
		/* setup domain */
		final TableContentWithInnerChild parent = TestFactory.eINSTANCE.createTableContentWithInnerChild();
		final TableContentWithInnerChild middle = TestFactory.eINSTANCE.createTableContentWithInnerChild();
		final TableContentWithInnerChild child = TestFactory.eINSTANCE.createTableContentWithInnerChild();
		parent.setInnerChild(middle);
		middle.setInnerChild(child);

		/* setup view */
		final VView view = VViewFactory.eINSTANCE.createView();

		/* setup control to add */
		final VControl vControl = VViewFactory.eINSTANCE.createControl();
		vControl.setDomainModelReference(
			TestPackage.eINSTANCE.getTableContentWithInnerChild_Stuff(),
			Arrays.asList(
				TestPackage.eINSTANCE.getTableContentWithInnerChild_InnerChild(),
				TestPackage.eINSTANCE.getTableContentWithInnerChild_InnerChild()));

		/*
		 * construct a situation where the observed object is null. This is valid according to
		 * org.eclipse.core.databinding.observable.IObserving.getObserved() javadoc, so we have to prepare for this.
		 * Easiest way to achieve this for testing is to mock the mapping provider
		 */
		new ViewModelContextImpl(view, parent) {

			@SuppressWarnings("unchecked")
			@Override
			public <T> T getService(Class<T> serviceType) {
				if (EMFFormsMappingProviderManager.class == serviceType) {
					final EMFFormsMappingProviderManager mock = Mockito.mock(EMFFormsMappingProviderManager.class);
					Mockito.doReturn(Collections.singleton(UniqueSetting.createSetting(null, null))).when(mock)
						.getAllSettingsFor(vControl.getDomainModelReference(), parent);
					return (T) mock;
				}
				return super.getServiceWithoutLog(serviceType);
			}
		};
		ViewModelContextFactory.INSTANCE.createViewModelContext(view, parent);

		/* act */
		view.getChildren().add(vControl);

		/* assert no NPE */
	}

	@Test
	public void testValidate_Iterable() {
		final AtomicReference<Collection<EObject>> validated = new AtomicReference<>();

		// CHECKSTYLE.OFF: AnonInnerLength - it's a test
		final ValidationService validationService = new ValidationService() {

			@Override
			public void validate(Collection<EObject> eObjects) {
				validated.set(eObjects);
			}

			@Override
			public void instantiate(ViewModelContext context) {
				// Not interesting
			}

			@Override
			public int getPriority() {
				// Not interesting
				return 0;
			}

			@Override
			public void dispose() {
				// Not interesting
			}

			@Override
			public void childViewModelContextAdded(ViewModelContext childContext) {
				// Not interesting
			}

			@Override
			public void removeValidationProvider(ValidationProvider validationProvider, boolean revalidate) {
				// Not interesting
			}

			@Override
			public void removeValidationProvider(ValidationProvider validationProvider) {
				// Not interesting
			}

			@Override
			public void registerValidationListener(ViewValidationListener listener) {
				// TODO Auto-generated method stub
			}

			@Override
			public void deregisterValidationListener(ViewValidationListener listener) {
				// Not interesting
			}

			@Override
			public void addValidationProvider(ValidationProvider validationProvider, boolean revalidate) {
				// Not interesting
			}

			@Override
			public void addValidationProvider(ValidationProvider validationProvider) {
				// Not interesting
			}
		};
		// CHECKSTYLE.ON: AnonInnerLength

		final List<EObject> eObjects = Arrays.asList(
			mock(EObject.class, "a"),
			mock(EObject.class, "b"),
			mock(EObject.class, "c"));

		final Iterable<EObject> iterable = eObjects::iterator;
		validationService.validate(iterable);

		assertThat("No collection passed to validation service", validated.get(), notNullValue());
		assertThat("Collection has wrong size", validated.get().size(), is(eObjects.size()));
		assertThat("Collection has wrong elements", new ArrayList<>(validated.get()), equalTo(eObjects));
	}

}
