/*******************************************************************************
 * Copyright (c) 2007, 2010 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.common.utility.tests.internal.model.value.prefs;

import java.util.prefs.NodeChangeEvent;
import java.util.prefs.NodeChangeListener;
import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;

import org.eclipse.jpt.common.utility.internal.ReflectionTools;
import org.eclipse.jpt.common.utility.internal.model.value.SimplePropertyValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.prefs.PreferencePropertyValueModel;
import org.eclipse.jpt.common.utility.model.Model;
import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent;
import org.eclipse.jpt.common.utility.model.listener.ChangeAdapter;
import org.eclipse.jpt.common.utility.model.listener.ChangeListener;
import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener;
import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel;

@SuppressWarnings("nls")
public class PreferencePropertyValueModelTests extends PreferencesTestCase {
	private WritablePropertyValueModel<Preferences> nodeHolder;
	PreferencePropertyValueModel<String> preferenceAdapter;
	PropertyChangeEvent event;
	PropertyChangeListener listener;
	boolean listenerRemoved = false;
	PreferenceChangeEvent preferenceEvent;
	private static final String KEY_NAME = "foo";
	private static final String STRING_VALUE = "original string value";

	public PreferencePropertyValueModelTests(String name) {
		super(name);
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		this.testNode.put(KEY_NAME, STRING_VALUE);

		this.nodeHolder = new SimplePropertyValueModel<Preferences>(this.testNode);
		this.preferenceAdapter = new PreferencePropertyValueModel<String>(this.nodeHolder, KEY_NAME);
		this.listener = this.buildValueChangeListener();
		this.preferenceAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener);
		this.event = null;
	}

	@Override
	protected void tearDown() throws Exception {
		super.tearDown();
	}

	private PropertyChangeListener buildValueChangeListener() {
		return new PropertyChangeListener() {
			public void propertyChanged(PropertyChangeEvent e) {
				if (PreferencePropertyValueModelTests.this.event != null) {
					throw new IllegalStateException("unexpected this.event: " + e);
				}
				PreferencePropertyValueModelTests.this.event = e;
			}
		};
	}

	public void testSubjectHolder() throws Exception {
		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
		assertNull(this.event);

		String ANOTHER_STRING_VALUE = "some other value";
		Preferences anotherNode = this.classNode.node("another test node");
		anotherNode.put(KEY_NAME, ANOTHER_STRING_VALUE);

		this.nodeHolder.setValue(anotherNode);
		this.verifyEvent(STRING_VALUE, ANOTHER_STRING_VALUE);
		assertEquals(ANOTHER_STRING_VALUE, this.preferenceAdapter.getValue());
		
		this.event = null;
		this.nodeHolder.setValue(null);
		this.verifyEvent(ANOTHER_STRING_VALUE, null);
		assertNull(this.preferenceAdapter.getValue());
		
		this.event = null;
		this.nodeHolder.setValue(this.testNode);
		this.verifyEvent(null, STRING_VALUE);
		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
	}

	public void testPreferenceChange() throws Exception {
		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
		assertNull(this.event);

		this.testNode.put(KEY_NAME, STRING_VALUE + STRING_VALUE);
		this.waitForEventQueueToClear();
		this.verifyEvent(STRING_VALUE, STRING_VALUE + STRING_VALUE);
		assertEquals(STRING_VALUE + STRING_VALUE, this.preferenceAdapter.getValue());
		
		this.event = null;
		this.testNode.remove(KEY_NAME);
		this.waitForEventQueueToClear();
		this.verifyEvent(STRING_VALUE + STRING_VALUE, null);
		assertNull(this.preferenceAdapter.getValue());
		
		this.event = null;
		this.testNode.put(KEY_NAME, STRING_VALUE);
		this.waitForEventQueueToClear();
		this.verifyEvent(null, STRING_VALUE);
		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
	}

	public void testValue() throws Exception {
		assertEquals(STRING_VALUE, this.testNode.get(KEY_NAME, "<missing preference>"));
		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
	}

	public void testSetValue() throws Exception {
		String ANOTHER_STRING_VALUE = "some other value";
		this.preferenceAdapter.setValue(ANOTHER_STRING_VALUE);
		assertEquals(ANOTHER_STRING_VALUE, this.preferenceAdapter.getValue());
		assertEquals(ANOTHER_STRING_VALUE, this.testNode.get(KEY_NAME, "<missing preference>"));
	}

	public void testHasListeners() throws Exception {
		assertTrue(this.preferenceAdapter.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
		assertTrue(this.nodeHasAnyPrefListeners(this.testNode));
		this.preferenceAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener);
		assertFalse(this.nodeHasAnyPrefListeners(this.testNode));
		assertFalse(this.preferenceAdapter.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));

		ChangeListener listener2 = this.buildChangeListener();
		this.preferenceAdapter.addChangeListener(listener2);
		assertTrue(this.preferenceAdapter.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
		assertTrue(this.nodeHasAnyPrefListeners(this.testNode));
		this.preferenceAdapter.removeChangeListener(listener2);
		assertFalse(this.nodeHasAnyPrefListeners(this.testNode));
		assertFalse(this.preferenceAdapter.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
	}

	private ChangeListener buildChangeListener() {
		return new ChangeAdapter() {
			@Override
			public void propertyChanged(PropertyChangeEvent e) {
				if (PreferencePropertyValueModelTests.this.event != null) {
					throw new IllegalStateException("unexpected this.event: " + e);
				}
				PreferencePropertyValueModelTests.this.event = e;
			}
		};
	}

	public void testRemoveAndReAddPreference() throws Exception {
		assertEquals(STRING_VALUE, this.testNode.get(KEY_NAME, null));
		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
		assertNull(this.event);

		// remove the preference entirely...
		this.testNode.remove(KEY_NAME);
		this.waitForEventQueueToClear();
		assertNull(this.testNode.get(KEY_NAME, null));
		this.verifyEvent(STRING_VALUE, null);
		assertNull(this.preferenceAdapter.getValue());

		// ...then re-add it with the same key
		this.event = null;
		this.testNode.put(KEY_NAME, STRING_VALUE);
		this.waitForEventQueueToClear();
		assertEquals(STRING_VALUE, this.testNode.get(KEY_NAME, null));
		this.verifyEvent(null, STRING_VALUE);
		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
	}

	public void testDefaultValue() throws Exception {
		// rebuild the adapter with a default value
		String DEFAULT_VALUE = "default value";
		this.preferenceAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener);
		this.preferenceAdapter = new PreferencePropertyValueModel<String>(this.nodeHolder, KEY_NAME, DEFAULT_VALUE);
		this.preferenceAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener);

		assertEquals(STRING_VALUE, this.testNode.get(KEY_NAME, null));
		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
		assertNull(this.event);

		// remove the preference entirely...
		this.testNode.remove(KEY_NAME);
		this.waitForEventQueueToClear();
		assertNull(this.testNode.get(KEY_NAME, null));
		this.verifyEvent(STRING_VALUE, DEFAULT_VALUE);
		assertEquals(DEFAULT_VALUE, this.preferenceAdapter.getValue());

		// ...then re-add it with the same key
		this.event = null;
		this.testNode.put(KEY_NAME, STRING_VALUE);
		this.waitForEventQueueToClear();
		assertEquals(STRING_VALUE, this.testNode.get(KEY_NAME, null));
		this.verifyEvent(DEFAULT_VALUE, STRING_VALUE);
		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
	}

	public void testUnsynchronizedValue() throws Exception {
		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
		assertNull(this.event);

		// remove the this.listener so the adapter no longer listens to the preference
		this.preferenceAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener);

		this.testNode.put(KEY_NAME, STRING_VALUE + STRING_VALUE);
		this.waitForEventQueueToClear();
		// no this.event should have been fired...
		assertNull(this.event);
		// ...and the adapter's value should be null
		assertNull(this.preferenceAdapter.getValue());
		
		this.testNode.remove(KEY_NAME);
		this.waitForEventQueueToClear();
		assertNull(this.event);
		assertNull(this.preferenceAdapter.getValue());
		
		this.testNode.put(KEY_NAME, STRING_VALUE);
		this.waitForEventQueueToClear();
		assertNull(this.event);
		assertNull(this.preferenceAdapter.getValue());

		// add the this.listener so the adapter synchs
		this.preferenceAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener);
		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
	}

	public void testIntegerPreference() throws Exception {
		// stop listening to the node and convert it to an integer
		this.preferenceAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener);

		PreferencePropertyValueModel<Integer> integerPreferenceAdapter = new PreferencePropertyValueModel<Integer>(this.nodeHolder, KEY_NAME);
		this.testNode.putInt(KEY_NAME, 123);
		integerPreferenceAdapter = PreferencePropertyValueModel.forInteger(this.testNode, KEY_NAME, 0);
		integerPreferenceAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener);
		assertEquals(new Integer(123), integerPreferenceAdapter.getValue());
		assertNull(this.event);

		this.testNode.putInt(KEY_NAME, 246);
		this.waitForEventQueueToClear();
		this.verifyEvent(integerPreferenceAdapter, new Integer(123), new Integer(246));
		assertEquals(new Integer(246), integerPreferenceAdapter.getValue());
		
		this.event = null;
		this.testNode.remove(KEY_NAME);
		this.waitForEventQueueToClear();
		this.verifyEvent(integerPreferenceAdapter, new Integer(246), new Integer(0));
		assertEquals(new Integer(0), integerPreferenceAdapter.getValue());
		
		this.event = null;
		this.testNode.putInt(KEY_NAME, 123);
		this.waitForEventQueueToClear();
		this.verifyEvent(integerPreferenceAdapter, new Integer(0), new Integer(123));
		assertEquals(new Integer(123), integerPreferenceAdapter.getValue());
	}

	/**
	 * test a situation where
	 * - we are listening to the node when it gets removed from the preferences "repository"
	 * - we get notification that it has been removed
	 * - we try to remove our this.listener
	 * - the node will throw an IllegalStateException - the adapter should handle it OK...
	 */
	public void testRemoveNode() throws Exception {
		assertTrue(this.preferenceAdapter.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));

		Preferences parent = this.testNode.parent();
		parent.addNodeChangeListener(this.buildParentNodeChangeListener());
		this.testNode.removeNode();
		this.testNode.flush();		// this seems to be required for the this.event to trigger...
		this.waitForEventQueueToClear();

		assertTrue(this.listenerRemoved);
		assertTrue(this.preferenceAdapter.hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
	}

	private NodeChangeListener buildParentNodeChangeListener() {
		return new NodeChangeListener() {
			public void childAdded(NodeChangeEvent e) {
				throw new IllegalStateException("unexpected this.event: " + e);
			}
			public void childRemoved(NodeChangeEvent e) {
				if (e.getChild() == PreferencePropertyValueModelTests.this.testNode) {
					PreferencePropertyValueModelTests.this.preferenceAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, PreferencePropertyValueModelTests.this.listener);
					// this line of code will not execute if the line above triggers an exception
					PreferencePropertyValueModelTests.this.listenerRemoved = true;
				}
			}
		};
	}

	public void testSetSameValue() {
		assertNull(this.event);
		assertNull(this.preferenceEvent);
		this.testNode.addPreferenceChangeListener(this.buildPreferenceChangeListener());

		String ANOTHER_STRING_VALUE = "some other value";
		this.preferenceAdapter.setValue(ANOTHER_STRING_VALUE);

		this.verifyEvent(STRING_VALUE, ANOTHER_STRING_VALUE);
		this.waitForEventQueueToClear();
		this.verifyPreferenceEvent(ANOTHER_STRING_VALUE);

		// now set to *same* value - nothing should happen...
		this.event = null;
		this.preferenceEvent = null;
		this.preferenceAdapter.setValue(ANOTHER_STRING_VALUE);

		assertNull(this.event);
		assertNull(this.preferenceEvent);
	}

	public void testSetSameValueForcePassThrough() throws Exception {
		assertNull(this.event);
		assertNull(this.preferenceEvent);

		this.preferenceAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener);
		this.preferenceAdapter = new AlwaysUpdatePreferencePropertyValueModel<String>(this.nodeHolder, KEY_NAME);
		this.preferenceAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener);

		this.testNode.addPreferenceChangeListener(this.buildPreferenceChangeListener());

		String ANOTHER_STRING_VALUE = "some other value";
		this.preferenceAdapter.setValue(ANOTHER_STRING_VALUE);

		this.verifyEvent(STRING_VALUE, ANOTHER_STRING_VALUE);
		this.waitForEventQueueToClear();
		this.verifyPreferenceEvent(ANOTHER_STRING_VALUE);

		// now set to *same* value - only one this.event should fire
		this.event = null;
		this.preferenceEvent = null;
		this.preferenceAdapter.setValue(ANOTHER_STRING_VALUE);

		assertNull(this.event);
		this.waitForEventQueueToClear();
		this.verifyPreferenceEvent(ANOTHER_STRING_VALUE);
		assertNull(this.event);
	}

	private PreferenceChangeListener buildPreferenceChangeListener() {
		return new PreferenceChangeListener() {
			public void preferenceChange(PreferenceChangeEvent evt) {
				PreferencePropertyValueModelTests.this.preferenceEvent = evt;
			}
		};
	}

	private void verifyEvent(Model source, Object oldValue, Object newValue) {
		assertNotNull(this.event);
		assertEquals(source, this.event.getSource());
		assertEquals(PropertyValueModel.VALUE, this.event.getPropertyName());
		assertEquals(oldValue, this.event.getOldValue());
		assertEquals(newValue, this.event.getNewValue());
	}

	private void verifyEvent(Object oldValue, Object newValue) {
		this.verifyEvent(this.preferenceAdapter, oldValue, newValue);
	}

	private void verifyPreferenceEvent(Object newValue) {
		assertNotNull(this.preferenceEvent);
		assertEquals(this.testNode, this.preferenceEvent.getSource());
		assertEquals(KEY_NAME, this.preferenceEvent.getKey());
		assertEquals(newValue, this.preferenceEvent.getNewValue());
		assertEquals(newValue, this.testNode.get(KEY_NAME, "<missing preference>"));
	}

	private boolean nodeHasAnyPrefListeners(Preferences node) throws Exception {
		PreferenceChangeListener[] prefListeners = (PreferenceChangeListener[]) ReflectionTools.getFieldValue(node, "prefListeners");
		return prefListeners.length > 0;
	}


	/**
	 * Use this adapter to test out always passing through the new value
	 * to the preference.
	 */
	private class AlwaysUpdatePreferencePropertyValueModel<P> extends PreferencePropertyValueModel<P> {

		AlwaysUpdatePreferencePropertyValueModel(PropertyValueModel<Preferences> preferencesHolder, String key) {
			super(preferencesHolder, key);
		}

		@Override
		protected boolean preferenceIsToBeSet(Object oldValue, Object newValue) {
			return true;
		}

	}

}
