/*******************************************************************************
 * Copyright (c) 2008 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)
 ******************************************************************************/

package org.eclipse.core.tests.internal.databinding.observable;

import junit.framework.Test;
import junit.framework.TestSuite;

import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.internal.databinding.observable.ValidatedObservableValue;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.databinding.conformance.MutableObservableValueContractTest;
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
import org.eclipse.jface.databinding.conformance.util.CurrentRealm;
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;

/**
 * @since 3.2
 * 
 */
public class ValidatedObservableValueTest extends AbstractDefaultRealmTestCase {
	private ValidatedObservableValue validated;
	private ObservableValueStub target;
	private IObservableValue validationStatus;

	private Object oldValue;
	private Object newValue;

	protected void setUp() throws Exception {
		super.setUp();
		oldValue = new Object();
		newValue = new Object();
		target = new ObservableValueStub(Realm.getDefault());
		target.setValue(oldValue);
		validationStatus = new WritableValue(ValidationStatus.ok(),
				IStatus.class);
		validated = new ValidatedObservableValue(target, validationStatus);
	}

	public void testConstructor_RequireObservablesOnSameRealm() {
		CurrentRealm realm1 = new CurrentRealm(true);
		CurrentRealm realm2 = new CurrentRealm(true);
		target = new ObservableValueStub(realm1);
		validationStatus = new WritableValue(realm2);
		try {
			new ValidatedObservableValue(target, validationStatus);
			fail("Expected exception--target and validation status should have the same realm");
		} catch (RuntimeException expected) {
		}
	}

	public void testIsStale_WhenTargetIsStale() {
		assertFalse(target.isStale());
		assertFalse(validated.isStale());

		target.fireStale();

		assertTrue(target.isStale());
		assertTrue(validated.isStale());
	}

	public void testIsStale_WhileChangesPending() {
		assertFalse(target.isStale());
		assertFalse(validated.isStale());

		validationStatus.setValue(ValidationStatus.error("error"));

		// The validated observable goes stale only when the target changes
		// value but the validation status is not OK.
		assertFalse(target.isStale());
		assertFalse(validated.isStale());

		target.setValue(newValue);

		assertFalse(target.isStale());
		assertTrue(validated.isStale());

		validationStatus.setValue(ValidationStatus.ok());

		assertFalse(validated.isStale());
	}

	public void testGetValueType_SameAsTarget() {
		assertEquals(target.getValueType(), validated.getValueType());
	}

	public void testGetValue_InitialValue() {
		assertEquals(oldValue, target.getValue());
		assertEquals(oldValue, validated.getValue());
	}

	public void testGetValue_WhileChangesPending() {
		assertEquals(oldValue, target.getValue());
		assertEquals(oldValue, validated.getValue());

		validationStatus.setValue(ValidationStatus.error("error"));

		assertEquals(oldValue, target.getValue());
		assertEquals(oldValue, validated.getValue());

		target.setValue(newValue);

		assertEquals(newValue, target.getValue());
		assertEquals(oldValue, validated.getValue());

		validationStatus.setValue(ValidationStatus.ok());

		assertEquals(newValue, validated.getValue());
	}

	public void testSetValue_PropagatesToTarget() {
		validated.setValue(newValue);

		assertEquals(newValue, validated.getValue());
		assertEquals(newValue, target.getValue());
	}

	public void testSetValue_PropagatesToTargetWhileStatusNotOK() {
		validationStatus.setValue(ValidationStatus.error("error"));

		validated.setValue(newValue);

		assertEquals(newValue, validated.getValue());
		assertEquals(newValue, target.getValue());
		assertFalse(validated.isStale());
	}

	public void testSetValue_CachesGetValueFromTarget() {
		Object overrideValue = target.overrideValue = new Object();

		assertEquals(oldValue, validated.getValue());
		assertEquals(oldValue, target.getValue());

		validationStatus.setValue(ValidationStatus.error("error"));

		validated.setValue(newValue);

		assertEquals(overrideValue, target.getValue());
		assertEquals(overrideValue, validated.getValue());
	}

	public void testSetValue_SingleValueChangeEvent() {
		ValueChangeEventTracker tracker = ValueChangeEventTracker
				.observe(validated);

		validated.setValue(newValue);
		assertEquals(1, tracker.count);
		assertEquals(oldValue, tracker.event.diff.getOldValue());
		assertEquals(newValue, tracker.event.diff.getNewValue());
	}

	public void testSetValue_SingleValueChangeEventWhileInvalid() {
		ValueChangeEventTracker tracker = ValueChangeEventTracker
				.observe(validated);

		validationStatus.setValue(ValidationStatus.error("error"));
		validated.setValue(newValue);
		assertEquals(1, tracker.count);
		assertEquals(oldValue, tracker.event.diff.getOldValue());
		assertEquals(newValue, tracker.event.diff.getNewValue());
	}

	public void testSetValue_FiresSingleValueChangeEventWithTargetOverride() {
		ValueChangeEventTracker tracker = ValueChangeEventTracker
				.observe(validated);

		Object overrideValue = new Object();
		target.overrideValue = overrideValue;
		validated.setValue(newValue);

		assertEquals(1, tracker.count);
		assertEquals(oldValue, tracker.event.diff.getOldValue());
		assertEquals(overrideValue, tracker.event.diff.getNewValue());
	}

	public void testSetValue_FiresValueChangeEvent() {
		ValueChangeEventTracker targetTracker = ValueChangeEventTracker
				.observe(target);
		ValueChangeEventTracker validatedTracker = ValueChangeEventTracker
				.observe(validated);

		validated.setValue(newValue);

		assertEquals(1, targetTracker.count);
		assertEquals(oldValue, targetTracker.event.diff.getOldValue());
		assertEquals(newValue, targetTracker.event.diff.getNewValue());

		assertEquals(1, validatedTracker.count);
		assertEquals(oldValue, validatedTracker.event.diff.getOldValue());
		assertEquals(newValue, validatedTracker.event.diff.getNewValue());
	}

	public void testIsStale_MatchTargetStaleness() {
		target.forceStale = true;
		target.fireStale();

		assertTrue(target.isStale());
		assertTrue(validated.isStale());

		target.setValue(newValue);

		assertTrue(target.isStale());
		assertTrue(validated.isStale());
	}

	static class ObservableValueStub extends AbstractObservableValue {
		private Object value;
		private boolean stale;
		private boolean forceStale;

		Object overrideValue;

		public ObservableValueStub(Realm realm) {
			super(realm);
		}

		protected Object doGetValue() {
			return value;
		}

		protected void doSetValue(Object value) {
			Object oldValue = this.value;
			if (overrideValue != null)
				value = overrideValue;
			this.value = value;
			stale = forceStale;
			fireValueChange(Diffs.createValueDiff(oldValue, value));
		}

		public Object getValueType() {
			return Object.class;
		}

		protected void fireStale() {
			stale = true;
			super.fireStale();
		}

		public boolean isStale() {
			return stale;
		}
	}

	public static Test suite() {
		TestSuite suite = new TestSuite(ValidatedObservableValueTest.class.getName());
		suite.addTestSuite(ValidatedObservableValueTest.class);
		suite.addTest(MutableObservableValueContractTest.suite(new Delegate()));
		return suite;
	}

	static class Delegate extends AbstractObservableValueContractDelegate {
		private Object valueType = new Object();

		public IObservableValue createObservableValue(Realm realm) {
			return new ValidatedObservableValueStub(realm, valueType);
		}

		public Object createValue(IObservableValue observable) {
			return new Object();
		}

		public Object getValueType(IObservableValue observable) {
			return valueType;
		}

		public void change(IObservable observable) {
			ValidatedObservableValueStub validated = (ValidatedObservableValueStub) observable;
			IObservableValue target = validated.target;
			target.setValue(createValue(validated));
		}
	}

	static class ValidatedObservableValueStub extends ValidatedObservableValue {
		final IObservableValue target;
		final IObservableValue validationStatus;

		ValidatedObservableValueStub(Realm realm, Object valueType) {
			this(new WritableValue(realm, null, valueType), new WritableValue(
					realm, ValidationStatus.ok(), IStatus.class));
		}

		private ValidatedObservableValueStub(IObservableValue target,
				IObservableValue validationStatus) {
			super(target, validationStatus);
			this.target = target;
			this.validationStatus = validationStatus;
		}
	}

}