/*******************************************************************************
 * Copyright (c) 2005, 2013 Oracle. 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/.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.common.utility.tests.internal.iterator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import junit.framework.TestCase;
import org.eclipse.jpt.common.utility.internal.iterator.CompositeIterator;
import org.eclipse.jpt.common.utility.internal.iterator.IteratorTools;

@SuppressWarnings("nls")
public class CompositeIteratorTests
	extends TestCase
{
	public CompositeIteratorTests(String name) {
		super(name);
	}

	public void testHasAnother() {
		this.verifyHasAnother(this.buildCompositeIterator());
	}

	public void testHasAnother2() {
		this.verifyHasAnother(this.buildCompositeIterator2());
	}

	public void testHasAnother3() {
		this.verifyHasAnother(this.buildCompositeIterator3());
	}

	void verifyHasAnother(Iterator<String> stream) {
		this.verifyHasAnother(8, stream);
	}

	void verifyHasAnother(int expected, Iterator<String> stream) {
		int i = 0;
		while (stream.hasNext()) {
			stream.next();
			i++;
		}
		assertEquals(expected, i);
	}

	public void testAnother() {
		this.verifyAnother(this.buildCompositeIterator());
	}

	public void testAnother2() {
		this.verifyAnother(this.buildCompositeIterator2());
	}

	public void testAnother3() {
		this.verifyAnother(this.buildCompositeIterator3());
	}

	void verifyAnother(Iterator<String> stream) {
		this.verifyAnother(1, stream);
	}

	void verifyAnother(int start, Iterator<String> stream) {
		int index = start;
		while (stream.hasNext()) {
			assertEquals("bogus element", String.valueOf(index++), stream.next().substring(0, 1));
		}
	}

	public void testRemove() {
		this.verifyRemove();
	}

	protected void verifyRemove() {
		List<String> list1 = this.buildList1();
		Object lastElement1 = list1.get(list1.size() - 1);
		List<String> list2 = this.buildList2();
		List<String> list3 = this.buildList3();

		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
		list.add(list1.listIterator());
		list.add(list2.listIterator());
		list.add(list3.listIterator());

		Iterator<String> stream = this.buildCompositeIterator(list.listIterator());
		while (stream.hasNext()) {
			Object next = stream.next();
			if (next.equals("333")) {
				stream.remove();
			}
			// test special case - where we are between iterators
			if (next.equals(lastElement1)) {
				// this will trigger the next iterator to be loaded
				stream.hasNext();
				// now try to remove from the previous iterator
				stream.remove();
			}
		}
		stream.remove();

		assertEquals("nothing removed from collection 1", this.buildList1().size() - 2, list1.size());
		assertFalse("element still in collection 1", list1.contains("333"));
		assertFalse("last element still in collection 1", list1.contains(lastElement1));
		assertTrue("wrong element removed from collection 1", list1.contains("22"));

		assertEquals("nothing removed from collection 3", this.buildList3().size() - 1, list3.size());
		assertFalse("element still in collection 3", list3.contains("88888888"));
		assertTrue("wrong element removed from collection 3", list3.contains("666666"));
	}

	public void testSingleElement() {
		String item = "0";
		this.verifyHasAnother(9, this.buildCompositeIterator(item, this.buildCompositeIterator()));
		this.verifyAnother(0, this.buildCompositeIterator(item, this.buildCompositeIterator()));
	}

	public void testNoSuchElementException() {
		this.verifyNoSuchElementException(this.buildCompositeIterator());
	}

	void verifyNoSuchElementException(Iterator<String> stream) {
		boolean exCaught = false;
		String string = null;
		while (stream.hasNext()) {
			string = stream.next();
		}
		try {
			string = stream.next();
		} catch (NoSuchElementException ex) {
			exCaught = true;
		}
		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
	}

	public void testUnsupportedOperationException() {
		this.verifyUnsupportedOperationException(this.buildUnmodifiableCompositeIterator());
	}

	void verifyUnsupportedOperationException(Iterator<String> stream) {
		boolean exCaught = false;
		while (stream.hasNext()) {
			Object string = stream.next();
			if (string.equals("333")) {
				try {
					stream.remove();
				} catch (UnsupportedOperationException ex) {
					exCaught = true;
				}
			}
		}
		assertTrue("UnsupportedOperationException not thrown", exCaught);
	}

	public void testIllegalStateException() {
		this.verifyIllegalStateException();
	}

	void verifyIllegalStateException() {
		this.verifyIllegalStateException(this.buildCompositeIterator());
	}

	void verifyIllegalStateException(Iterator<String> stream) {
		boolean exCaught = false;
		try {
			stream.remove();
		} catch (IllegalStateException ex) {
			exCaught = true;
		}
		assertTrue("IllegalStateException not thrown", exCaught);
	}

	public void testEmptyHasAnother1() {
		this.verifyEmptyHasAnother(this.buildEmptyCompositeIterator1());
	}

	void verifyEmptyHasAnother(Iterator<String> stream) {
		int i = 0;
		while (stream.hasNext()) {
			stream.next();
			i++;
		}
		assertEquals(0, i);
	}

	public void testEmptyNoSuchElementException1() {
		this.verifyNoSuchElementException(this.buildEmptyCompositeIterator1());
	}

	public void testEmptyIllegalStateException1() {
		this.verifyEmptyIllegalStateException1();
	}

	void verifyEmptyIllegalStateException1() {
		this.verifyIllegalStateException(this.buildEmptyCompositeIterator1());
	}

	public void testEmptyHasAnother2() {
		this.verifyEmptyHasAnother(this.buildEmptyCompositeIterator2());
	}

	public void testEmptyNoSuchElementException2() {
		this.verifyNoSuchElementException(this.buildEmptyCompositeIterator2());
	}

	public void testEmptyIllegalStateException2() {
		this.verifyEmptyIllegalStateException2();
	}

	void verifyEmptyIllegalStateException2() {
		this.verifyIllegalStateException(this.buildEmptyCompositeIterator2());
	}

	Iterator<String> buildCompositeIterator() {
		return this.buildCompositeIterator(this.buildIterators());
	}

	Iterator<String> buildEmptyCompositeIterator1() {
		return this.buildCompositeIterator(this.buildEmptyIterators1());
	}

	Iterator<String> buildEmptyCompositeIterator2() {
		return this.buildCompositeIterator(this.buildEmptyIterators2());
	}

	Iterator<String> buildUnmodifiableCompositeIterator() {
		return this.buildCompositeIterator(this.buildUnmodifiableIterators());
	}

	// leave unchecked so we can override in subclass
	@SuppressWarnings("unchecked")
	Iterator<String> buildCompositeIterator(@SuppressWarnings("rawtypes") Iterator iterators) {
		return new CompositeIterator<String>(iterators);
	}

	// use vararg constructor
	@SuppressWarnings("unchecked")
	Iterator<String> buildCompositeIterator2() {
		return IteratorTools.concatenate(this.buildIterator1(), this.buildIterator2(), this.buildIterator3());
	}

	// use vararg constructor
	@SuppressWarnings("unchecked")
	Iterator<String> buildCompositeIterator3() {
		return IteratorTools.concatenate(new Iterator[] { this.buildIterator1(), this.buildIterator2(), this.buildIterator3() });
	}

	Iterator<String> buildCompositeIterator(String string, Iterator<String> iterator) {
		return IteratorTools.insert(string, iterator);
	}

	ListIterator<Iterator<String>> buildIterators() {
		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
		list.add(this.buildIterator1());
		list.add(this.buildIterator2());
		list.add(this.buildIterator3());
		return list.listIterator();
	}

	ListIterator<Iterator<String>> buildEmptyIterators1() {
		return this.buildEmptyIteratorIterator();
	}

	ListIterator<Iterator<String>> buildEmptyIterators2() {
		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
		list.add(this.buildEmptyStringIterator());
		list.add(this.buildEmptyStringIterator());
		list.add(this.buildEmptyStringIterator());
		return list.listIterator();
	}

	ListIterator<Iterator<String>> buildUnmodifiableIterators() {
		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
		list.add(this.buildUnmodifiableIterator1());
		list.add(this.buildUnmodifiableIterator2());
		list.add(this.buildUnmodifiableIterator3());
		return list.listIterator();
	}

	ListIterator<String> buildIterator1() {
		return this.buildList1().listIterator();
	}

	ListIterator<String> buildIterator2() {
		return this.buildList2().listIterator();
	}

	ListIterator<String> buildIterator3() {
		return this.buildList3().listIterator();
	}

	ListIterator<String> buildUnmodifiableIterator1() {
		return this.buildUnmodifiableList1().listIterator();
	}

	ListIterator<String> buildUnmodifiableIterator2() {
		return this.buildUnmodifiableList2().listIterator();
	}

	ListIterator<String> buildUnmodifiableIterator3() {
		return this.buildUnmodifiableList3().listIterator();
	}

	ListIterator<Iterator<String>> buildEmptyIteratorIterator() {
		return (new ArrayList<Iterator<String>>()).listIterator();
	}

	ListIterator<String> buildEmptyStringIterator() {
		return (new ArrayList<String>()).listIterator();
	}

	List<String> buildList1() {
		List<String> list = new ArrayList<String>();
		list.add("1");
		list.add("22");
		list.add("333");
		list.add("4444");
		return list;
	}

	List<String> buildList2() {
		return new ArrayList<String>();
	}

	List<String> buildList3() {
		List<String> list = new ArrayList<String>();
		list.add("55555");
		list.add("666666");
		list.add("7777777");
		list.add("88888888");
		return list;
	}

	List<String> buildUnmodifiableList1() {
		return Collections.unmodifiableList(this.buildList1());
	}

	List<String> buildUnmodifiableList2() {
		return Collections.unmodifiableList(this.buildList2());
	}

	List<String> buildUnmodifiableList3() {
		return Collections.unmodifiableList(this.buildList3());
	}

}
