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

import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

import junit.framework.TestCase;

import org.eclipse.jpt.utility.internal.ArrayTools;
import org.eclipse.jpt.utility.internal.Bag;
import org.eclipse.jpt.utility.internal.HashBag;
import org.eclipse.jpt.utility.internal.Tools;

@SuppressWarnings("nls")
public class HashBagTests extends TestCase {
	private HashBag<String> bag;

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

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		this.bag = this.buildBag();
	}

	private HashBag<String> buildBag() {
		HashBag<String> b = new HashBag<String>();
		b.add(null);
		b.add(new String("one"));
		b.add(new String("two"));
		b.add(new String("two"));
		b.add(new String("three"));
		b.add(new String("three"));
		b.add(new String("three"));
		b.add(new String("four"));
		b.add(new String("four"));
		b.add(new String("four"));
		b.add(new String("four"));
		return b;
	}

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

	private Collection<String> buildCollection() {
		Collection<String> c = new ArrayList<String>();
		c.add(new String("foo"));
		c.add(new String("foo"));
		c.add(new String("bar"));
		c.add(new String("bar"));
		c.add(new String("bar"));
		return c;
	}

	public void testCtorCollection() {
		Collection<String> c = this.buildCollection();
		Bag<String> b = new HashBag<String>(c);
		for (String s : c) {
			assertTrue(b.contains(s));
		}
	}

	public void testCtorIntFloat() {
		boolean exCaught;

		exCaught = false;
		try {
			this.bag = new HashBag<String>(-20, 0.66f);
		} catch (IllegalArgumentException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);

		exCaught = false;
		try {
			this.bag = new HashBag<String>(20, -0.66f);
		} catch (IllegalArgumentException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);
	}

	public void testAdd() {
		// the other adds took place in setUp
		assertTrue(this.bag.add("five"));

		assertTrue(this.bag.contains("one"));
		assertTrue(this.bag.contains("two"));
		assertTrue(this.bag.contains("three"));
		assertTrue(this.bag.contains("four"));
		assertTrue(this.bag.contains("five"));
	}

	public void testAddCount() {
		// the other adds took place in setUp
		this.bag.add("minus3", -3);
		this.bag.add("zero", 0);
		this.bag.add("five", 5);

		assertFalse(this.bag.contains("minus3"));
		assertFalse(this.bag.contains("zero"));
		assertEquals(1, this.bag.count("one"));
		assertEquals(2, this.bag.count("two"));
		assertEquals(3, this.bag.count("three"));
		assertEquals(4, this.bag.count("four"));
		assertEquals(5, this.bag.count("five"));

		this.bag.add("three", 2);
		assertEquals(5, this.bag.count("three"));
	}

	public void testAddAll() {
		Collection<String> c = this.buildCollection();
		assertTrue(this.bag.addAll(c));
		for (String s : c) {
			assertTrue(this.bag.contains(s));
		}
	}

	public void testClear() {
		assertTrue(this.bag.contains("one"));
		assertTrue(this.bag.contains("two"));
		assertTrue(this.bag.contains("three"));
		assertTrue(this.bag.contains("four"));
		assertTrue(this.bag.contains(null));
		assertEquals(11, this.bag.size());
		this.bag.clear();
		assertFalse(this.bag.contains("one"));
		assertFalse(this.bag.contains("two"));
		assertFalse(this.bag.contains("three"));
		assertFalse(this.bag.contains("four"));
		assertFalse(this.bag.contains(null));
		assertEquals(0, this.bag.size());
	}

	public void testClone() {
		Bag<String> bag2 = this.bag.clone();
		assertTrue(this.bag != bag2);
		assertEquals(this.bag, bag2);
		assertTrue(this.bag.hashCode() == bag2.hashCode());
	}

	public void testContains() {
		assertTrue(this.bag.contains(null));
		assertTrue(this.bag.contains("one"));
		assertTrue(this.bag.contains("two"));
		assertTrue(this.bag.contains("three"));
		assertTrue(this.bag.contains("four"));
		assertTrue(this.bag.contains(new String("four")));
		assertTrue(this.bag.contains("fo" + "ur"));
		assertFalse(this.bag.contains("five"));
	}

	public void testContainsAll() {
		Collection<String> c = new ArrayList<String>();
		c.add(null);
		c.add(new String("one"));
		c.add(new String("two"));
		c.add(new String("three"));
		c.add(new String("four"));
		assertTrue(this.bag.containsAll(c));
	}

	public void testCount() {
		assertEquals(0, this.bag.count("zero"));
		assertEquals(1, this.bag.count("one"));
		assertEquals(2, this.bag.count("two"));
		assertEquals(3, this.bag.count("three"));
		assertEquals(4, this.bag.count("four"));
		assertEquals(0, this.bag.count("five"));
	}

	public void testEquals() {
		Bag<String> bag2 = this.buildBag();
		assertEquals(this.bag, bag2);
		bag2.add("five");
		assertFalse(this.bag.equals(bag2));
		Collection<String> c = new ArrayList<String>(this.bag);
		assertFalse(this.bag.equals(c));
	}

	public void testHashCode() {
		Bag<String> bag2 = this.buildBag();
		assertEquals(this.bag.hashCode(), bag2.hashCode());
	}

	public void testIsEmpty() {
		assertFalse(this.bag.isEmpty());
		this.bag.clear();
		assertTrue(this.bag.isEmpty());
		this.bag.add("foo");
		assertFalse(this.bag.isEmpty());
	}

	public void testEmptyIterator() {
		this.bag.clear();
		Iterator<String> iterator = this.bag.iterator();
		assertFalse(iterator.hasNext());

		boolean exCaught = false;
		Object element = null;
		try {
			element = iterator.next();
			fail(element.toString());
		} catch (NoSuchElementException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);

		exCaught = false;
		try {
			iterator.remove();
		} catch (IllegalStateException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);
	}

	public void testIterator() {
		int i = 0;
		Iterator<String> iterator = this.bag.iterator();
		assertTrue(iterator.hasNext());
		while (iterator.hasNext()) {
			iterator.next();
			i++;
		}
		assertEquals(11, i);
		assertFalse(iterator.hasNext());

		boolean exCaught = false;
		Object element = null;
		try {
			element = iterator.next();
			fail(element.toString());
		} catch (NoSuchElementException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);

		iterator.remove();
		assertEquals(10, this.bag.size());

		exCaught = false;
		try {
			iterator.remove();
		} catch (IllegalStateException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);

		// start over
		iterator = this.bag.iterator();
		this.bag.add("five");
		exCaught = false;
		try {
			iterator.next();
		} catch (ConcurrentModificationException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);
	}

	public void testUniqueIterator() {
		int i = 0;
		Iterator<String> iterator = this.bag.uniqueIterator();
		assertTrue(iterator.hasNext());
		while (iterator.hasNext()) {
			iterator.next();
			i++;
		}
		assertEquals(5, i);
		assertFalse(iterator.hasNext());

		boolean exCaught = false;
		Object element = null;
		try {
			element = iterator.next();
			fail(element.toString());
		} catch (NoSuchElementException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);

		// start over
		iterator = this.bag.uniqueIterator();
		Object next = null;
		while (iterator.hasNext() && !"four".equals(next)) {
			next = iterator.next();
		}
		iterator.remove();
		assertEquals(7, this.bag.size());

		exCaught = false;
		try {
			iterator.remove();
		} catch (IllegalStateException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);

		// start over
		iterator = this.bag.uniqueIterator();
		this.bag.add("five");
		exCaught = false;
		try {
			iterator.next();
		} catch (ConcurrentModificationException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);
	}

	public void testEntries() {
		int i = 0;
		Iterator<Bag.Entry<String>> iterator = this.bag.entries();
		assertTrue(iterator.hasNext());
		while (iterator.hasNext()) {
			iterator.next();
			i++;
		}
		assertEquals(5, i);
		assertFalse(iterator.hasNext());

		boolean exCaught = false;
		Object element = null;
		try {
			element = iterator.next();
			fail(element.toString());
		} catch (NoSuchElementException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);

		// start over
		iterator = this.bag.entries();
		Bag.Entry<String> next = null;
		while (iterator.hasNext()) {
			next = iterator.next();
			if (next.getElement().equals("four")) {
				iterator.remove();
				break;
			}
		}
		assertEquals(7, this.bag.size());

		exCaught = false;
		try {
			iterator.remove();
		} catch (IllegalStateException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);

		// start over
		iterator = this.bag.entries();
		this.bag.add("five");
		exCaught = false;
		try {
			iterator.next();
		} catch (ConcurrentModificationException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);
	}

	public void testHashingDistribution() throws Exception {
		Bag<String> bigBag = new HashBag<String>();
		for (int i = 0; i < 10000; i++) {
			bigBag.add("object" + i);
		}

		java.lang.reflect.Field field = bigBag.getClass().getDeclaredField("table");
		field.setAccessible(true);
		Object[] table = (Object[]) field.get(bigBag);
		int bucketCount = table.length;
		int filledBucketCount = 0;
		for (Object o : table) {
			if (o != null) {
				filledBucketCount++;
			}
		}
		float loadFactor = ((float) filledBucketCount) / ((float) bucketCount);
		if ((loadFactor < 0.20) || (loadFactor > 0.80)) {
			String msg = "poor load factor: " + loadFactor;
			if (Tools.jvmIsSun()) {
				fail(msg);
			} else {
				// poor load factor is seen in the Eclipse build environment for some reason...
				System.out.println(this.getClass().getName() + '.' + this.getName() + " - " + msg);
				TestTools.printSystemProperties();
			}
		}
	}

	public void testRemove() {
		assertTrue(this.bag.remove("one"));
		assertFalse(this.bag.contains("one"));
		assertFalse(this.bag.remove("one"));

		assertTrue(this.bag.remove("two"));
		assertTrue(this.bag.remove("two"));
		assertFalse(this.bag.contains("two"));
		assertFalse(this.bag.remove("two"));
	}

	public void testRemoveCount() {
		assertFalse(this.bag.remove("one", 0));
		assertTrue(this.bag.contains("one"));

		assertTrue(this.bag.remove("one", 1));
		assertFalse(this.bag.contains("one"));
		assertFalse(this.bag.remove("one"));

		assertFalse(this.bag.remove("two", -3));
		assertTrue(this.bag.remove("two", 1));
		assertTrue(this.bag.contains("two"));

		assertTrue(this.bag.remove("two", 1));
		assertFalse(this.bag.contains("two"));
		assertFalse(this.bag.remove("two"));

		assertTrue(this.bag.remove("three", 3));
		assertFalse(this.bag.contains("three"));
		assertFalse(this.bag.remove("three"));
	}

	public void testRemoveAll() {
		Collection<String> c = new ArrayList<String>();
		c.add("one");
		c.add("three");
		assertTrue(this.bag.removeAll(c));
		assertFalse(this.bag.contains("one"));
		assertFalse(this.bag.contains("three"));
		assertFalse(this.bag.remove("one"));
		assertFalse(this.bag.remove("three"));
		assertFalse(this.bag.removeAll(c));
	}

	public void testRetainAll() {
		Collection<String> c = new ArrayList<String>();
		c.add("one");
		c.add("three");
		assertTrue(this.bag.retainAll(c));
		assertTrue(this.bag.contains("one"));
		assertTrue(this.bag.contains("three"));
		assertFalse(this.bag.contains("two"));
		assertFalse(this.bag.contains("four"));
		assertFalse(this.bag.remove("two"));
		assertFalse(this.bag.remove("four"));
		assertFalse(this.bag.retainAll(c));
	}

	public void testSize() {
		assertTrue(this.bag.size() == 11);
		this.bag.add("five");
		this.bag.add("five");
		this.bag.add("five");
		this.bag.add("five");
		this.bag.add("five");
		assertEquals(16, this.bag.size());
	}

	public void testSerialization() throws Exception {
		Bag<String> bag2 = TestTools.serialize(this.bag);

		assertTrue("same object?", this.bag != bag2);
		assertEquals(11, bag2.size());
		assertEquals(this.bag, bag2);
		// look for similar elements
		assertTrue(bag2.contains(null));
		assertTrue(bag2.contains("one"));
		assertTrue(bag2.contains("two"));
		assertTrue(bag2.contains("three"));
		assertTrue(bag2.contains("four"));

		int nullCount = 0, oneCount = 0, twoCount = 0, threeCount = 0, fourCount = 0;
		for (String s : bag2) {
			if (s == null) {
				nullCount++;
			} else if (s.equals("one")) {
				oneCount++;
			} else if (s.equals("two")) {
				twoCount++;
			} else if (s.equals("three")) {
				threeCount++;
			} else if (s.equals("four")) {
				fourCount++;
			}
		}
		assertEquals(1, nullCount);
		assertEquals(1, oneCount);
		assertEquals(2, twoCount);
		assertEquals(3, threeCount);
		assertEquals(4, fourCount);
	}

	public void testToArray() {
		Object[] a = this.bag.toArray();
		assertEquals(11, a.length);
		assertTrue(ArrayTools.contains(a, null));
		assertTrue(ArrayTools.contains(a, "one"));
		assertTrue(ArrayTools.contains(a, "two"));
		assertTrue(ArrayTools.contains(a, "three"));
		assertTrue(ArrayTools.contains(a, "four"));
	}

	public void testToArrayObjectArray() {
		String[] a = new String[12];
		a[11] = "not null";
		String[] b = this.bag.toArray(a);
		assertEquals(a, b);
		assertEquals(12, a.length);
		assertTrue(ArrayTools.contains(a, null));
		assertTrue(ArrayTools.contains(a, "one"));
		assertTrue(ArrayTools.contains(a, "two"));
		assertTrue(ArrayTools.contains(a, "three"));
		assertTrue(ArrayTools.contains(a, "four"));
		assertTrue(a[11] == null);
	}

	public void testToString() {
		String s = this.bag.toString();
		assertTrue(s.startsWith("["));
		assertTrue(s.endsWith("]"));
		int commaCount = 0;
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) == ',') {
				commaCount++;
			}
		}
		assertEquals(10, commaCount);
		assertTrue(s.indexOf("one") != -1);
		assertTrue(s.indexOf("two") != -1);
		assertTrue(s.indexOf("three") != -1);
		assertTrue(s.indexOf("four") != -1);
		assertTrue(s.indexOf("null") != -1);
	}

}
