/*
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/publicdomain/zero/1.0/
 * Other contributors include Andrew Wright, Jeffrey Hayes,
 * Pat Fisher, Mike Judd.
 */

package jsr166;

import junit.framework.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Vector;
import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteArrayListTest extends JSR166TestCase {

    static CopyOnWriteArrayList<Integer> populatedArray(int n) {
        CopyOnWriteArrayList<Integer> a = new CopyOnWriteArrayList<Integer>();
        assertTrue(a.isEmpty());
        for (int i = 0; i < n; i++)
            a.add(i);
        assertFalse(a.isEmpty());
        assertEquals(n, a.size());
        return a;
    }

    static CopyOnWriteArrayList<Integer> populatedArray(Integer[] elements) {
        CopyOnWriteArrayList<Integer> a = new CopyOnWriteArrayList<Integer>();
        assertTrue(a.isEmpty());
        for (int i = 0; i < elements.length; i++)
            a.add(elements[i]);
        assertFalse(a.isEmpty());
        assertEquals(elements.length, a.size());
        return a;
    }

    /**
     * a new list is empty
     */
    public void testConstructor() {
        CopyOnWriteArrayList a = new CopyOnWriteArrayList();
        assertTrue(a.isEmpty());
    }

    /**
     * new list contains all elements of initializing array
     */
    public void testConstructor2() {
        Integer[] ints = new Integer[SIZE];
        for (int i = 0; i < SIZE-1; ++i)
            ints[i] = new Integer(i);
        CopyOnWriteArrayList a = new CopyOnWriteArrayList(ints);
        for (int i = 0; i < SIZE; ++i)
            assertEquals(ints[i], a.get(i));
    }

    /**
     * new list contains all elements of initializing collection
     */
    public void testConstructor3() {
        Integer[] ints = new Integer[SIZE];
        for (int i = 0; i < SIZE-1; ++i)
            ints[i] = new Integer(i);
        CopyOnWriteArrayList a = new CopyOnWriteArrayList(Arrays.asList(ints));
        for (int i = 0; i < SIZE; ++i)
            assertEquals(ints[i], a.get(i));
    }

    /**
     * addAll adds each element from the given collection
     */
    public void testAddAll() {
        CopyOnWriteArrayList full = populatedArray(3);
        Vector v = new Vector();
        v.add(three);
        v.add(four);
        v.add(five);
        full.addAll(v);
        assertEquals(6, full.size());
    }

    /**
     * addAllAbsent adds each element from the given collection that did not
     * already exist in the List
     */
    public void testAddAllAbsent() {
        CopyOnWriteArrayList full = populatedArray(3);
        Vector v = new Vector();
        v.add(three);
        v.add(four);
        v.add(one); // will not add this element
        full.addAllAbsent(v);
        assertEquals(5, full.size());
    }

    /**
     * addIfAbsent will not add the element if it already exists in the list
     */
    public void testAddIfAbsent() {
        CopyOnWriteArrayList full = populatedArray(SIZE);
        full.addIfAbsent(one);
        assertEquals(SIZE, full.size());
    }

    /**
     * addIfAbsent adds the element when it does not exist in the list
     */
    public void testAddIfAbsent2() {
        CopyOnWriteArrayList full = populatedArray(SIZE);
        full.addIfAbsent(three);
        assertTrue(full.contains(three));
    }

    /**
     * clear removes all elements from the list
     */
    public void testClear() {
        CopyOnWriteArrayList full = populatedArray(SIZE);
        full.clear();
        assertEquals(0, full.size());
    }

    /**
     * Cloned list is equal
     */
    public void testClone() {
        CopyOnWriteArrayList l1 = populatedArray(SIZE);
        CopyOnWriteArrayList l2 = (CopyOnWriteArrayList)(l1.clone());
        assertEquals(l1, l2);
        l1.clear();
        assertFalse(l1.equals(l2));
    }

    /**
     * contains is true for added elements
     */
    public void testContains() {
        CopyOnWriteArrayList full = populatedArray(3);
        assertTrue(full.contains(one));
        assertFalse(full.contains(five));
    }

    /**
     * adding at an index places it in the indicated index
     */
    public void testAddIndex() {
        CopyOnWriteArrayList full = populatedArray(3);
        full.add(0, m1);
        assertEquals(4, full.size());
        assertEquals(m1, full.get(0));
        assertEquals(zero, full.get(1));

        full.add(2, m2);
        assertEquals(5, full.size());
        assertEquals(m2, full.get(2));
        assertEquals(two, full.get(4));
    }

    /**
     * lists with same elements are equal and have same hashCode
     */
    public void testEquals() {
        CopyOnWriteArrayList a = populatedArray(3);
        CopyOnWriteArrayList b = populatedArray(3);
        assertTrue(a.equals(b));
        assertTrue(b.equals(a));
        assertEquals(a.hashCode(), b.hashCode());
        a.add(m1);
        assertFalse(a.equals(b));
        assertFalse(b.equals(a));
        b.add(m1);
        assertTrue(a.equals(b));
        assertTrue(b.equals(a));
        assertEquals(a.hashCode(), b.hashCode());
    }

    /**
     * containsAll returns true for collection with subset of elements
     */
    public void testContainsAll() {
        CopyOnWriteArrayList full = populatedArray(3);
        Vector v = new Vector();
        v.add(one);
        v.add(two);
        assertTrue(full.containsAll(v));
        v.add(six);
        assertFalse(full.containsAll(v));
    }

    /**
     * get returns the value at the given index
     */
    public void testGet() {
        CopyOnWriteArrayList full = populatedArray(3);
        assertEquals(0, full.get(0));
    }

    /**
     * indexOf gives the index for the given object
     */
    public void testIndexOf() {
        CopyOnWriteArrayList full = populatedArray(3);
        assertEquals(1, full.indexOf(one));
        assertEquals(-1, full.indexOf("puppies"));
    }

    /**
     * indexOf gives the index based on the given index
     * at which to start searching
     */
    public void testIndexOf2() {
        CopyOnWriteArrayList full = populatedArray(3);
        assertEquals(1, full.indexOf(one, 0));
        assertEquals(-1, full.indexOf(one, 2));
    }

    /**
     * isEmpty returns true when empty, else false
     */
    public void testIsEmpty() {
        CopyOnWriteArrayList empty = new CopyOnWriteArrayList();
        CopyOnWriteArrayList full = populatedArray(SIZE);
        assertTrue(empty.isEmpty());
        assertFalse(full.isEmpty());
    }

    /**
     * iterator() returns an iterator containing the elements of the
     * list in insertion order
     */
    public void testIterator() {
        Collection empty = new CopyOnWriteArrayList();
        assertFalse(empty.iterator().hasNext());
        try {
            empty.iterator().next();
            shouldThrow();
        } catch (NoSuchElementException success) {}

        Integer[] elements = new Integer[SIZE];
        for (int i = 0; i < SIZE; i++)
            elements[i] = i;
        Collections.shuffle(Arrays.asList(elements));
        Collection<Integer> full = populatedArray(elements);

        Iterator it = full.iterator();
        for (int j = 0; j < SIZE; j++) {
            assertTrue(it.hasNext());
            assertEquals(elements[j], it.next());
        }
        assertFalse(it.hasNext());
        try {
            it.next();
            shouldThrow();
        } catch (NoSuchElementException success) {}
    }

    /**
     * iterator.remove throws UnsupportedOperationException
     */
    public void testIteratorRemove() {
        CopyOnWriteArrayList full = populatedArray(SIZE);
        Iterator it = full.iterator();
        it.next();
        try {
            it.remove();
            shouldThrow();
        } catch (UnsupportedOperationException success) {}
    }

    /**
     * toString contains toString of elements
     */
    public void testToString() {
        assertEquals("[]", new CopyOnWriteArrayList().toString());
        CopyOnWriteArrayList full = populatedArray(3);
        String s = full.toString();
        for (int i = 0; i < 3; ++i)
            assertTrue(s.contains(String.valueOf(i)));
        assertEquals(new ArrayList(full).toString(),
                     full.toString());
    }

    /**
     * lastIndexOf returns the index for the given object
     */
    public void testLastIndexOf1() {
        CopyOnWriteArrayList full = populatedArray(3);
        full.add(one);
        full.add(three);
        assertEquals(3, full.lastIndexOf(one));
        assertEquals(-1, full.lastIndexOf(six));
    }

    /**
     * lastIndexOf returns the index from the given starting point
     */
    public void testLastIndexOf2() {
        CopyOnWriteArrayList full = populatedArray(3);
        full.add(one);
        full.add(three);
        assertEquals(3, full.lastIndexOf(one, 4));
        assertEquals(-1, full.lastIndexOf(three, 3));
    }

    /**
     * listIterator traverses all elements
     */
    public void testListIterator1() {
        CopyOnWriteArrayList full = populatedArray(SIZE);
        ListIterator i = full.listIterator();
        int j;
        for (j = 0; i.hasNext(); j++)
            assertEquals(j, i.next());
        assertEquals(SIZE, j);
    }

    /**
     * listIterator only returns those elements after the given index
     */
    public void testListIterator2() {
        CopyOnWriteArrayList full = populatedArray(3);
        ListIterator i = full.listIterator(1);
        int j;
        for (j = 0; i.hasNext(); j++)
            assertEquals(j+1, i.next());
        assertEquals(2, j);
    }

    /**
     * remove(int) removes and returns the object at the given index
     */
    public void testRemove_int() {
        int SIZE = 3;
        for (int i = 0; i < SIZE; i++) {
            CopyOnWriteArrayList full = populatedArray(SIZE);
            assertEquals(i, full.remove(i));
            assertEquals(SIZE - 1, full.size());
            assertFalse(full.contains(new Integer(i)));
        }
    }

    /**
     * remove(Object) removes the object if found and returns true
     */
    public void testRemove_Object() {
        int SIZE = 3;
        for (int i = 0; i < SIZE; i++) {
            CopyOnWriteArrayList full = populatedArray(SIZE);
            assertFalse(full.remove(new Integer(-42)));
            assertTrue(full.remove(new Integer(i)));
            assertEquals(SIZE - 1, full.size());
            assertFalse(full.contains(new Integer(i)));
        }
        CopyOnWriteArrayList x = new CopyOnWriteArrayList(Arrays.asList(4, 5, 6));
        assertTrue(x.remove(new Integer(6)));
        assertEquals(x, Arrays.asList(4, 5));
        assertTrue(x.remove(new Integer(4)));
        assertEquals(x, Arrays.asList(5));
        assertTrue(x.remove(new Integer(5)));
        assertEquals(x, Arrays.asList());
        assertFalse(x.remove(new Integer(5)));
    }

    /**
     * removeAll removes all elements from the given collection
     */
    public void testRemoveAll() {
        CopyOnWriteArrayList full = populatedArray(3);
        Vector v = new Vector();
        v.add(one);
        v.add(two);
        full.removeAll(v);
        assertEquals(1, full.size());
    }

    /**
     * set changes the element at the given index
     */
    public void testSet() {
        CopyOnWriteArrayList full = populatedArray(3);
        assertEquals(2, full.set(2, four));
        assertEquals(4, full.get(2));
    }

    /**
     * size returns the number of elements
     */
    public void testSize() {
        CopyOnWriteArrayList empty = new CopyOnWriteArrayList();
        CopyOnWriteArrayList full = populatedArray(SIZE);
        assertEquals(SIZE, full.size());
        assertEquals(0, empty.size());
    }

    /**
     * toArray() returns an Object array containing all elements from
     * the list in insertion order
     */
    public void testToArray() {
        Object[] a = new CopyOnWriteArrayList().toArray();
        assertTrue(Arrays.equals(new Object[0], a));
        assertSame(Object[].class, a.getClass());

        Integer[] elements = new Integer[SIZE];
        for (int i = 0; i < SIZE; i++)
            elements[i] = i;
        Collections.shuffle(Arrays.asList(elements));
        Collection<Integer> full = populatedArray(elements);

        assertTrue(Arrays.equals(elements, full.toArray()));
        assertSame(Object[].class, full.toArray().getClass());
    }

    /**
     * toArray(Integer array) returns an Integer array containing all
     * elements from the list in insertion order
     */
    public void testToArray2() {
        Collection empty = new CopyOnWriteArrayList();
        Integer[] a;

        a = new Integer[0];
        assertSame(a, empty.toArray(a));

        a = new Integer[SIZE/2];
        Arrays.fill(a, 42);
        assertSame(a, empty.toArray(a));
        assertNull(a[0]);
        for (int i = 1; i < a.length; i++)
            assertEquals(42, (int) a[i]);

        Integer[] elements = new Integer[SIZE];
        for (int i = 0; i < SIZE; i++)
            elements[i] = i;
        Collections.shuffle(Arrays.asList(elements));
        Collection<Integer> full = populatedArray(elements);

        Arrays.fill(a, 42);
        assertTrue(Arrays.equals(elements, full.toArray(a)));
        for (int i = 0; i < a.length; i++)
            assertEquals(42, (int) a[i]);
        assertSame(Integer[].class, full.toArray(a).getClass());

        a = new Integer[SIZE];
        Arrays.fill(a, 42);
        assertSame(a, full.toArray(a));
        assertTrue(Arrays.equals(elements, a));

        a = new Integer[2*SIZE];
        Arrays.fill(a, 42);
        assertSame(a, full.toArray(a));
        assertTrue(Arrays.equals(elements, Arrays.copyOf(a, SIZE)));
        assertNull(a[SIZE]);
        for (int i = SIZE + 1; i < a.length; i++)
            assertEquals(42, (int) a[i]);
    }

    /**
     * sublists contains elements at indexes offset from their base
     */
    public void testSubList() {
        CopyOnWriteArrayList a = populatedArray(10);
        assertTrue(a.subList(1,1).isEmpty());
        for (int j = 0; j < 9; ++j) {
            for (int i = j ; i < 10; ++i) {
                List b = a.subList(j,i);
                for (int k = j; k < i; ++k) {
                    assertEquals(new Integer(k), b.get(k-j));
                }
            }
        }

        List s = a.subList(2, 5);
        assertEquals(3, s.size());
        s.set(2, m1);
        assertEquals(a.get(4), m1);
        s.clear();
        assertEquals(7, a.size());
    }

    // Exception tests

    /**
     * toArray throws an ArrayStoreException when the given array
     * can not store the objects inside the list
     */
    public void testToArray_ArrayStoreException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.add("zfasdfsdf");
            c.add("asdadasd");
            c.toArray(new Long[5]);
            shouldThrow();
        } catch (ArrayStoreException success) {}
    }

    /**
     * get throws an IndexOutOfBoundsException on a negative index
     */
    public void testGet1_IndexOutOfBoundsException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.get(-1);
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * get throws an IndexOutOfBoundsException on a too high index
     */
    public void testGet2_IndexOutOfBoundsException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.add("asdasd");
            c.add("asdad");
            c.get(100);
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * set throws an IndexOutOfBoundsException on a negative index
     */
    public void testSet1_IndexOutOfBoundsException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.set(-1,"qwerty");
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * set throws an IndexOutOfBoundsException on a too high index
     */
    public void testSet2() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.add("asdasd");
            c.add("asdad");
            c.set(100, "qwerty");
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * add throws an IndexOutOfBoundsException on a negative index
     */
    public void testAdd1_IndexOutOfBoundsException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.add(-1,"qwerty");
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * add throws an IndexOutOfBoundsException on a too high index
     */
    public void testAdd2_IndexOutOfBoundsException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.add("asdasd");
            c.add("asdasdasd");
            c.add(100, "qwerty");
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * remove throws an IndexOutOfBoundsException on a negative index
     */
    public void testRemove1_IndexOutOfBounds() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.remove(-1);
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * remove throws an IndexOutOfBoundsException on a too high index
     */
    public void testRemove2_IndexOutOfBounds() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.add("asdasd");
            c.add("adasdasd");
            c.remove(100);
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * addAll throws an IndexOutOfBoundsException on a negative index
     */
    public void testAddAll1_IndexOutOfBoundsException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.addAll(-1,new LinkedList());
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * addAll throws an IndexOutOfBoundsException on a too high index
     */
    public void testAddAll2_IndexOutOfBoundsException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.add("asdasd");
            c.add("asdasdasd");
            c.addAll(100, new LinkedList());
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * listIterator throws an IndexOutOfBoundsException on a negative index
     */
    public void testListIterator1_IndexOutOfBoundsException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.listIterator(-1);
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * listIterator throws an IndexOutOfBoundsException on a too high index
     */
    public void testListIterator2_IndexOutOfBoundsException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.add("adasd");
            c.add("asdasdas");
            c.listIterator(100);
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * subList throws an IndexOutOfBoundsException on a negative index
     */
    public void testSubList1_IndexOutOfBoundsException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.subList(-1,100);
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * subList throws an IndexOutOfBoundsException on a too high index
     */
    public void testSubList2_IndexOutOfBoundsException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.add("asdasd");
            c.subList(1,100);
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * subList throws IndexOutOfBoundsException when the second index
     * is lower then the first
     */
    public void testSubList3_IndexOutOfBoundsException() {
        try {
            CopyOnWriteArrayList c = new CopyOnWriteArrayList();
            c.subList(3,1);
            shouldThrow();
        } catch (IndexOutOfBoundsException success) {}
    }

    /**
     * a deserialized serialized list is equal
     */
    public void testSerialization() throws Exception {
        List x = populatedArray(SIZE);
        List y = serialClone(x);

        assertNotSame(x, y);
        assertEquals(x.size(), y.size());
        assertEquals(x.toString(), y.toString());
        assertTrue(Arrays.equals(x.toArray(), y.toArray()));
        assertEquals(x, y);
        assertEquals(y, x);
        while (!x.isEmpty()) {
            assertFalse(y.isEmpty());
            assertEquals(x.remove(0), y.remove(0));
        }
        assertTrue(y.isEmpty());
    }

}
