/*******************************************************************************
 * Copyright (c) 2007, 2008 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.utility.tests.internal.model.value;

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

import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.model.value.SimpleListValueModel;
import org.eclipse.jpt.utility.model.event.ListChangeEvent;
import org.eclipse.jpt.utility.model.listener.ListChangeListener;
import org.eclipse.jpt.utility.model.value.ListValueModel;
import org.eclipse.jpt.utility.tests.internal.TestTools;

import junit.framework.TestCase;

public class SimpleListValueModelTests extends TestCase {
	private SimpleListValueModel<String> listHolder;
	ListChangeEvent event;
	String eventType;

	private static final String ADD = "add";
	private static final String REMOVE = "remove";
	private static final String REPLACE = "replace";
	private static final String MOVE = "move";
	private static final String CLEAR = "clear";
	private static final String CHANGE = "change";

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

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		this.listHolder = new SimpleListValueModel<String>(this.buildList());
	}

	private List<String> buildList() {
		List<String> result = new ArrayList<String>();
		result.add("foo");
		result.add("bar");
		result.add("baz");
		return result;
	}

	private List<String> buildAddList() {
		List<String> result = new ArrayList<String>();
		result.add("joo");
		result.add("jar");
		result.add("jaz");
		return result;
	}

//	private List<String> buildRemoveList() {
//		List<String> result = new ArrayList<String>();
//		result.add("foo");
//		result.add("bar");
//		return result;
//	}
//
	@Override
	protected void tearDown() throws Exception {
		TestTools.clear(this);
		super.tearDown();
	}

	public void testIterator() {
		assertEquals(this.buildList(), CollectionTools.list(this.listHolder.iterator()));
	}

	public void testListIterator() {
		assertEquals(this.buildList(), CollectionTools.list(this.listHolder.listIterator()));
	}

	public void testListIteratorInt() {
		assertEquals(CollectionTools.list(this.buildList().listIterator(1)), CollectionTools.list(this.listHolder.listIterator(1)));
	}

	public void testSize() {
		assertEquals(this.buildList().size(), this.listHolder.size());
	}

	private boolean listContains(Object item) {
		return CollectionTools.contains(this.listHolder.listIterator(), item);
	}

	private boolean listContainsAll(Collection<String> items) {
		return CollectionTools.containsAll(this.listHolder.listIterator(), items);
	}

	private boolean listContainsAny(Collection<String> items) {
		Set<String> set = CollectionTools.set(this.listHolder.iterator());
		for (Iterator<String> stream = items.iterator(); stream.hasNext(); ) {
			if (set.contains(stream.next())) {
				return true;
			}
		}
		return false;
	}

	public void testAddObject() {
		assertFalse(this.listContains("joo"));
		this.listHolder.add("joo");
		assertTrue(this.listContains("joo"));

		assertFalse(this.listContains(null));
		this.listHolder.add(null);
		assertTrue(this.listContains(null));
	}

	public void testAddIntObject() {
		assertFalse(this.listContains("joo"));
		this.listHolder.add(2, "joo");
		assertTrue(this.listContains("joo"));

		assertFalse(this.listContains(null));
		this.listHolder.add(0, null);
		assertTrue(this.listContains(null));
	}

	public void testAddAllCollection() {
		assertFalse(this.listContainsAny(this.buildAddList()));
		this.listHolder.addAll(this.buildAddList());
		assertTrue(this.listContainsAll(this.buildAddList()));
	}

	public void testAddAllIntCollection() {
		assertFalse(this.listContainsAny(this.buildAddList()));
		this.listHolder.addAll(2, this.buildAddList());
		assertTrue(this.listContainsAll(this.buildAddList()));
	}

	public void testClear() {
		assertFalse(this.listHolder.isEmpty());
		this.listHolder.clear();
		assertTrue(this.listHolder.isEmpty());
	}

	public void testContainsObject() {
		assertTrue(this.listHolder.contains("foo"));
		assertFalse(this.listHolder.contains("joo"));
	}

	public void testContainsAllCollection() {
		Collection<String> c = new ArrayList<String>();
		c.add("foo");
		c.add("bar");
		assertTrue(this.listHolder.containsAll(c));

		c.add("joo");
		assertFalse(this.listHolder.containsAll(c));
	}

	public void testEquals() {
		assertEquals(new SimpleListValueModel<String>(this.buildList()), this.listHolder);
		assertFalse(this.listHolder.equals(new SimpleListValueModel<String>(this.buildAddList())));
		assertFalse(this.listHolder.equals(this.buildList()));
		assertFalse(this.listHolder.equals(new SimpleListValueModel<String>()));
	}

	public void testGetInt() {
		assertEquals("foo", this.listHolder.get(0));
		assertEquals("bar", this.listHolder.get(1));
		assertEquals("baz", this.listHolder.get(2));
	}

	public void testHashCode() {
		assertEquals(new SimpleListValueModel<String>(this.buildList()).hashCode(), this.listHolder.hashCode());
	}

	public void testIndexOfObject() {
		assertEquals(0, this.listHolder.indexOf("foo"));
		assertEquals(1, this.listHolder.indexOf("bar"));
		assertEquals(2, this.listHolder.indexOf("baz"));
		assertEquals(-1, this.listHolder.indexOf("joo"));
	}

	public void testLastIndexOfObject() {
		assertEquals(0, this.listHolder.lastIndexOf("foo"));
		assertEquals(1, this.listHolder.lastIndexOf("bar"));
		assertEquals(2, this.listHolder.lastIndexOf("baz"));
		assertEquals(-1, this.listHolder.lastIndexOf("joo"));

		this.listHolder.add("foo");
		assertEquals(3, this.listHolder.lastIndexOf("foo"));
	}

	public void testIsEmpty() {
		assertFalse(this.listHolder.isEmpty());
		this.listHolder.clear();
		assertTrue(this.listHolder.isEmpty());
	}

	public void testRemove() {
		assertTrue(this.listContains("bar"));
		this.listHolder.remove(this.buildList().indexOf("bar"));
		assertFalse(this.listContains("bar"));

		this.listHolder.add(1, null);
		assertTrue(this.listContains(null));
		this.listHolder.remove(1);
		assertFalse(this.listContains(null));
	}

	public void testSetValues() {
		List<String> newList = new ArrayList<String>();
		newList.add("joo");
		newList.add("jar");
		newList.add("jaz");

		assertTrue(this.listContains("bar"));
		assertFalse(this.listContains("jar"));
		this.listHolder.setList(newList);
		assertFalse(this.listContains("bar"));
		assertTrue(this.listContains("jar"));

		this.listHolder.add(1, null);
		assertTrue(this.listContains(null));
		this.listHolder.remove(1);
		assertFalse(this.listContains(null));

		this.listHolder.setList(new ArrayList<String>());
		assertFalse(this.listContains("jar"));
	}

	public void testListChange1() {
		this.listHolder.addListChangeListener(this.buildListener());
		this.verifyListChange();
	}

	public void testListChange2() {
		this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
		this.verifyListChange();
	}

	private void verifyListChange() {
		this.event = null;
		this.eventType = null;
		this.listHolder.add(1, "joo");
		this.verifyEvent(ADD, 1, "joo");

		this.event = null;
		this.eventType = null;
		this.listHolder.add(1, null);
		this.verifyEvent(ADD, 1, null);

		this.event = null;
		this.eventType = null;
		this.listHolder.remove(1);
		this.verifyEvent(REMOVE, 1, null);

		this.event = null;
		this.eventType = null;
		this.listHolder.remove(1);
		this.verifyEvent(REMOVE, 1, "joo");

		this.event = null;
		this.eventType = null;
		this.listHolder.setList(this.buildList());
		this.verifyEvent(CHANGE);

		this.event = null;
		this.eventType = null;
		this.listHolder.addAll(0, this.buildList());
		this.verifyEvent(ADD);
		assertEquals(this.buildList(), CollectionTools.list(this.event.items()));

		this.event = null;
		this.eventType = null;
		this.listHolder.set(0, "joo");
		this.verifyEvent(REPLACE);
		assertFalse(CollectionTools.contains(this.event.items(), "foo"));
		assertTrue(CollectionTools.contains(this.event.items(), "joo"));
	}

	private ListChangeListener buildListener() {
		return new ListChangeListener() {
			public void itemsAdded(ListChangeEvent e) {
				SimpleListValueModelTests.this.eventType = ADD;
				SimpleListValueModelTests.this.event = e;
			}
			public void itemsRemoved(ListChangeEvent e) {
				SimpleListValueModelTests.this.eventType = REMOVE;
				SimpleListValueModelTests.this.event = e;
			}
			public void itemsReplaced(ListChangeEvent e) {
				SimpleListValueModelTests.this.eventType = REPLACE;
				SimpleListValueModelTests.this.event = e;
			}
			public void itemsMoved(ListChangeEvent e) {
				SimpleListValueModelTests.this.eventType = MOVE;
				SimpleListValueModelTests.this.event = e;
			}
			public void listCleared(ListChangeEvent e) {
				SimpleListValueModelTests.this.eventType = CLEAR;
				SimpleListValueModelTests.this.event = e;
			}
			public void listChanged(ListChangeEvent e) {
				SimpleListValueModelTests.this.eventType = CHANGE;
				SimpleListValueModelTests.this.event = e;
			}
		};
	}

	private void verifyEvent(String e) {
		assertEquals(e, this.eventType);
		assertEquals(this.listHolder, this.event.getSource());
		assertEquals(ListValueModel.LIST_VALUES, this.event.getListName());
	}

	private void verifyEvent(String e, int index, Object item) {
		this.verifyEvent(e);
		assertEquals(index, this.event.getIndex());
		assertEquals(item, this.event.items().next());
	}

}
