/*******************************************************************************
 * Copyright (c) 2008, 2009 Matthew Hall 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:
 *     Matthew Hall - initial API and implementation (bug 218269)
 *     Matthew Hall - bugs 237884, 251003, 332504
 *     Ovidio Mallo - bugs 240590, 238909, 251003, 247741, 235859
 ******************************************************************************/

package org.eclipse.core.tests.databinding.validation;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

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

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.AbstractObservable;
import org.eclipse.core.databinding.observable.ChangeEvent;
import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.core.databinding.observable.IChangeListener;
import org.eclipse.core.databinding.observable.ObservableTracker;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.databinding.validation.MultiValidator;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.internal.databinding.validation.ValidatedObservableValue;
import org.eclipse.core.runtime.AssertionFailedException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.databinding.conformance.util.CurrentRealm;
import org.eclipse.jface.databinding.conformance.util.StaleEventTracker;
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
import org.junit.Before;
import org.junit.Test;

public class MultiValidatorTest extends AbstractDefaultRealmTestCase {
	private DependencyObservableValue dependency;
	private MultiValidator validator;
	private IObservableValue validationStatus;

	@Before
	public void setUp() throws Exception {
		super.setUp();
		dependency = new DependencyObservableValue(null, IStatus.class);
		validator = new MultiValidator() {
			@Override
			protected IStatus validate() {
				return (IStatus) dependency.getValue();
			}
		};
		validationStatus = validator.getValidationStatus();
	}

	@Test
	public void testConstructor_NullArgument() {
		try {
			new MultiValidator(null) {
				@Override
				protected IStatus validate() {
					return null;
				}
			};
			fail("Expected AssertionFailedException");
		} catch (AssertionFailedException expected) {
		}
	}

	@Test
	public void testGetValidationStatus_NullResultYieldsOKStatus() {
		IStatus status = (IStatus) validationStatus.getValue();
		assertTrue(status.isOK()); // null -> OK
	}

	@Test
	public void testGetValidationStatus_ExceptionThrownYieldsErrorStatus() {
		final RuntimeException e = new RuntimeException("message");
		validator = new MultiValidator() {
			@Override
			protected IStatus validate() {
				throw e;
			}
		};
		assertEquals(ValidationStatus.error("message", e), validator.getValidationStatus().getValue());
	}

	@Test
	public void testGetValidationStatus_TracksWithDependency() {
		IStatus newStatus = ValidationStatus.error("error");
		dependency.setValue(newStatus);
		assertEquals(newStatus, validationStatus.getValue());
	}

	@Test
	public void testInit_AddsValidationProducer() {
		DataBindingContext dbc = new DataBindingContext();
		dbc.addValidationStatusProvider(validator);
		assertTrue(dbc.getValidationStatusProviders().contains(validator));
	}

	@Test
	public void testObserveValidatedValue_NullArgument() {
		try {
			validator.observeValidatedValue(null);
			fail("Expected AssertionFailedException");
		} catch (AssertionFailedException expected) {
		}
	}

	@Test
	public void testObserveValidatedValue_WrongRealm() {
		Realm otherRealm = new CurrentRealm(true);
		try {
			validator.observeValidatedValue(new WritableValue(otherRealm));
			fail("Expected AssertionFailedException");
		} catch (AssertionFailedException expected) {
		}
	}

	@Test
	public void testObserveValidatedValue_ReturnValue() {
		WritableValue target = new WritableValue();
		ValidatedObservableValue validated = (ValidatedObservableValue) validator.observeValidatedValue(target);

		target.setValue(new Object());
		assertEquals(target.getValue(), validated.getValue());

		dependency.setValue(ValidationStatus.error("error"));
		assertFalse(validated.isStale());

		target.setValue(new Object());
		assertTrue(validated.isStale());
		assertFalse(target.getValue().equals(validated.getValue()));

		dependency.setValue(ValidationStatus.info("info")); // considered valid
		assertEquals(target.getValue(), validated.getValue());
		assertFalse(validated.isStale());
	}

	@Test
	public void testBug237884_DisposeCausesNPE() {
		MultiValidator validator = new MultiValidator() {
			@Override
			protected IStatus validate() {
				return ValidationStatus.ok();
			}
		};
		try {
			validator.dispose();
		} catch (NullPointerException e) {
			fail("Bug 237884: MultiValidator.dispose() causes NPE");
		}
	}

	@Test
	public void testBug237884_MultipleDispose() {
		validator.dispose();
		validator.dispose();
	}

	@Test
	public void testBug237884_Comment3_ValidationStatusAsDependencyCausesStackOverflow() {
		dependency = new DependencyObservableValue(new Object(), Object.class);
		validator = new MultiValidator() {
			private int counter;

			@Override
			protected IStatus validate() {
				ObservableTracker.getterCalled(dependency);
				return ValidationStatus.info("info " + counter++);
			}
		};
		validationStatus = validator.getValidationStatus();

		// bug behavior: the validation status listener causes the validation
		// status observable to become a dependency of the validator.
		validationStatus.addChangeListener(new IChangeListener() {
			@Override
			public void handleChange(ChangeEvent event) {
				ObservableTracker.getterCalled(validationStatus);
			}
		});
		dependency.setValue(new Object());

		// at this point, because the validation status observable is a
		// dependency, changes to the validation status cause revalidation in an
		// infinite recursion.
		try {
			dependency.setValue(new Object());
		} catch (StackOverflowError e) {
			fail("Bug 237884: Accessing MultiValidator validation status from within listener "
					+ "causes infinite recursion");
		}
	}

	@Test
	public void testBug237884_ValidationStatusListenerCausesLoopingDependency() {
		validationStatus.addChangeListener(new IChangeListener() {
			@Override
			public void handleChange(ChangeEvent event) {
				ObservableTracker.getterCalled(validationStatus);
			}
		});
		assertFalse(validator.getTargets().contains(validationStatus));
		// trigger revalidation
		dependency.setValue(ValidationStatus.info("info"));
		assertFalse(validator.getTargets().contains(validationStatus));
	}

	@Test
	public void testRevalidate() {
		// Use this as an easy way to inject a validation status into the
		// validator without using an observable value.
		final IStatus[] status = new IStatus[] { ValidationStatus.ok() };

		class MyMultiValidator extends MultiValidator {
			@Override
			protected IStatus validate() {
				return status[0];
			}

			protected void callRevalidate() {
				revalidate();
			}
		}

		MyMultiValidator validator = new MyMultiValidator();

		// Initially, the validation status should always be in sync.
		assertSame(status[0], validator.getValidationStatus().getValue());

		// When the validation status depends on something different than the
		// IObservable dependency set, the MultiValidator cannot track those
		// changes automatically so the validation status will get inconsistent
		// without further ado.
		status[0] = ValidationStatus.error("");
		assertNotSame(status[0], validator.getValidationStatus().getValue());

		// By calling makeDirty(), the validation status should be updated.
		validator.callRevalidate();
		assertSame(status[0], validator.getValidationStatus().getValue());
	}

	@Test
	public void testBug237884_ValidationStatusAccessDuringValidationCausesLoopingDependency() {
		validator = new MultiValidator() {
			@Override
			protected IStatus validate() {
				ObservableTracker.getterCalled(getValidationStatus());
				return (IStatus) dependency.getValue();
			}
		};
		// trigger revalidation
		dependency.setValue(ValidationStatus.info("info"));
		assertFalse(validator.getTargets().contains(validationStatus));
	}

	@Test
	public void testBug240590_ValidationStatusSetWhileTrackingDependencies() {
		final IObservableValue noDependency = new WritableValue();
		validationStatus.addValueChangeListener(new IValueChangeListener() {
			@Override
			public void handleValueChange(ValueChangeEvent event) {
				// Explicitly track the faked dependency.
				ObservableTracker.getterCalled(noDependency);
			}
		});

		// Trigger a validation change.
		dependency.setValue(ValidationStatus.error("new error"));

		// Make sure the faked dependency has not been included in the
		// dependency set (the validator's targets).
		assertFalse(validator.getTargets().contains(noDependency));
	}

	@Test
	public void testValidationStaleness() {
		ValueChangeEventTracker validationChangeCounter = ValueChangeEventTracker.observe(validationStatus);

		StaleEventTracker validationStaleCounter = StaleEventTracker.observe(validationStatus);

		// Assert initial state.
		assertFalse(validationStatus.isStale());
		assertEquals(0, validationChangeCounter.count);
		assertEquals(0, validationStaleCounter.count);

		// Change to a stale state.
		dependency.setStale(true);
		assertTrue(validationStatus.isStale());
		assertEquals(0, validationChangeCounter.count);
		assertEquals(1, validationStaleCounter.count); // +1

		// The validation status is already stale so even if it gets another
		// stale event from its dependencies, it should not propagate that
		// event.
		dependency.fireStale();
		assertTrue(validationStatus.isStale());
		assertEquals(0, validationChangeCounter.count);
		assertEquals(1, validationStaleCounter.count);

		// Change the validation status while remaining stale.
		dependency.setValue(ValidationStatus.error("e1"));
		assertTrue(validationStatus.isStale());
		assertEquals(1, validationChangeCounter.count); // +1
		assertEquals(1, validationStaleCounter.count);

		// Move back to a non-stale state.
		dependency.setStale(false);
		assertFalse(dependency.isStale());
		assertFalse(validationStatus.isStale());
		assertEquals(2, validationChangeCounter.count); // +1
		assertEquals(1, validationStaleCounter.count);
	}

	@Test
	public void testStatusValueChangeWhileValidationStale() {
		// Change to a stale state.
		dependency.setStale(true);
		assertTrue(validationStatus.isStale());

		// Even if the validation is stale, we want the current value to be
		// tracked.
		dependency.setValue(ValidationStatus.error("e1"));
		assertTrue(validationStatus.isStale());
		assertEquals(dependency.getValue(), validationStatus.getValue());
		dependency.setValue(ValidationStatus.error("e2"));
		assertTrue(validationStatus.isStale());
		assertEquals(dependency.getValue(), validationStatus.getValue());
	}

	@Test
	public void testValidationStatusBecomesStaleThroughNewDependency() {
		final DependencyObservableValue nonStaleDependency = new DependencyObservableValue(ValidationStatus.ok(),
				IStatus.class);
		nonStaleDependency.setStale(false);

		final DependencyObservableValue staleDependency = new DependencyObservableValue(ValidationStatus.ok(),
				IStatus.class);
		staleDependency.setStale(true);

		validator = new MultiValidator() {
			@Override
			protected IStatus validate() {
				if (nonStaleDependency.getValue() != null) {
					return (IStatus) nonStaleDependency.getValue();
				}
				return (IStatus) staleDependency.getValue();
			}
		};
		validationStatus = validator.getValidationStatus();

		assertFalse(validationStatus.isStale());

		StaleEventTracker validationStaleCounter = StaleEventTracker.observe(validationStatus);
		assertEquals(0, validationStaleCounter.count);

		// Setting the status of the non-stale dependency to null leads to the
		// new stale dependency being accessed which in turn should trigger a
		// stale event.
		nonStaleDependency.setValue(null);
		assertTrue(validationStatus.isStale());
		assertEquals(1, validationStaleCounter.count);
	}

	@Test
	public void testBug251003_CompareDependenciesByIdentity() {
		DependencyObservable dependency1 = new DependencyObservable();
		DependencyObservable dependency2 = new DependencyObservable();
		assertEquals(dependency1, dependency2);
		assertNotSame(dependency1, dependency2);

		final List<DependencyObservable> dependencies = new ArrayList<DependencyObservable>();
		dependencies.add(dependency1);
		validator = new MultiValidator() {
			@Override
			protected IStatus validate() {
				for (Iterator<DependencyObservable> it = dependencies.iterator(); it.hasNext();)
					ObservableTracker.getterCalled(it.next());
				return null;
			}
		};

		// force init validation
		validationStatus = validator.getValidationStatus();

		IObservableList targets = validator.getTargets();
		assertEquals(1, targets.size());
		assertSame(dependency1, targets.get(0));

		dependencies.set(0, dependency2);
		dependency1.fireChange(); // force revalidate

		assertEquals(1, targets.size());
		assertSame(dependency2, targets.get(0));
	}

	@Test
	public void testBug251003_MissingDependencies() {
		final WritableList emptyListDependency = new WritableList();
		validator = new MultiValidator() {
			@Override
			protected IStatus validate() {
				ObservableTracker.getterCalled(emptyListDependency);
				return null;
			}
		};

		// Make sure the validation above is really triggered.
		validator.getValidationStatus().getValue();

		// emptyListDependency should be included in the dependency set.
		assertTrue(validator.getTargets().contains(emptyListDependency));
	}

	@Test
	public void testBug357568_MultiValidatorTargetAsDependency() {
		validator = new MultiValidator() {
			@Override
			protected IStatus validate() {
				ObservableTracker.getterCalled(dependency);
				ObservableTracker.getterCalled(new DependencyObservable());
				ObservableTracker.getterCalled(validator.getTargets());
				return null;
			}
		};

		validator.getValidationStatus().getValue();
		dependency.setValue(ValidationStatus.info("foo"));
	}

	@Test
	public void testBug357568_ValidationStatusAsDependency() {
		validator = new MultiValidator() {
			@Override
			protected IStatus validate() {
				return (IStatus) validator.getValidationStatus().getValue();
			}
		};

		validator.getValidationStatus();
	}

	private static class DependencyObservableValue extends WritableValue {
		private boolean stale = false;

		public DependencyObservableValue(Object initialValue, Object valueType) {
			super(initialValue, valueType);
		}

		@Override
		public boolean isStale() {
			ObservableTracker.getterCalled(this);
			return stale;
		}

		public void setStale(boolean stale) {
			if (this.stale != stale) {
				this.stale = stale;
				if (stale) {
					fireStale();
				} else {
					fireValueChange(Diffs.createValueDiff(doGetValue(), doGetValue()));
				}
			}
		}

		@Override
		protected void fireStale() {
			super.fireStale();
		}
	}

	private static class DependencyObservable extends AbstractObservable {
		public DependencyObservable() {
			super(Realm.getDefault());
		}

		@Override
		public boolean isStale() {
			return false;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == this)
				return true;
			if (obj == null)
				return false;
			return getClass() == obj.getClass();
		}

		@Override
		public int hashCode() {
			return getClass().hashCode();
		}

		@Override
		protected void fireChange() {
			// TODO Auto-generated method stub
			super.fireChange();
		}
	}
}
