/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.apache.commons.collections.iterators;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

import org.apache.commons.collections.MapIterator;

/**
 * Abstract class for testing the MapIterator interface.
 * <p>
 * This class provides a framework for testing an implementation of MapIterator.
 * Concrete subclasses must provide the list iterator to be tested.
 * They must also specify certain details of how the list iterator operates by
 * overriding the supportsXxx() methods if necessary.
 * 
 * @since Commons Collections 3.0
 * @version $Revision: 646780 $ $Date: 2008-04-10 13:48:07 +0100 (Thu, 10 Apr 2008) $
 * 
 * @author Stephen Colebourne
 */
public abstract class AbstractTestMapIterator extends AbstractTestIterator {

    /**
     * JUnit constructor.
     * 
     * @param testName  the test class name
     */
    public AbstractTestMapIterator(String testName) {
        super(testName);
    }

    //-----------------------------------------------------------------------
    /**
     * Implement this method to return a map iterator over an empty map.
     * 
     * @return an empty iterator
     */
    public abstract MapIterator makeEmptyMapIterator();

    /**
     * Implement this method to return a map iterator over a map with elements.
     * 
     * @return a full iterator
     */
    public abstract MapIterator makeFullMapIterator();

    /**
     * Implement this method to return the map which contains the same data as the
     * iterator.
     * 
     * @return a full map which can be updated
     */
    public abstract Map getMap();
    
    /**
     * Implement this method to return the confirmed map which contains the same
     * data as the iterator.
     * 
     * @return a full map which can be updated
     */
    public abstract Map getConfirmedMap();
    
    /**
     * Implements the abstract superclass method to return the list iterator.
     * 
     * @return an empty iterator
     */
    public final Iterator makeEmptyIterator() {
        return makeEmptyMapIterator();
    }

    /**
     * Implements the abstract superclass method to return the list iterator.
     * 
     * @return a full iterator
     */
    public final Iterator makeFullIterator() {
        return makeFullMapIterator();
    }

    /**
     * Whether or not we are testing an iterator that supports setValue().
     * Default is true.
     * 
     * @return true if Iterator supports set
     */
    public boolean supportsSetValue() {
        return true;
    }

    /**
     * Whether the get operation on the map structurally modifies the map,
     * such as with LRUMap. Default is false.
     * 
     * @return true if the get method structurally modifies the map
     */
    public boolean isGetStructuralModify() {
        return false;
    }
    
    /**
     * The values to be used in the add and set tests.
     * Default is two strings.
     */
    public Object[] addSetValues() {
        return new Object[] {"A", "B"};
    }

    //-----------------------------------------------------------------------
    /**
     * Test that the empty list iterator contract is correct.
     */
    public void testEmptyMapIterator() {
        if (supportsEmptyIterator() == false) {
            return;
        }

        MapIterator it = makeEmptyMapIterator();
        Map map = getMap();
        assertEquals(false, it.hasNext());
        
        // next() should throw a NoSuchElementException
        try {
            it.next();
            fail();
        } catch (NoSuchElementException ex) {}
        
        // getKey() should throw an IllegalStateException
        try {
            it.getKey();
            fail();
        } catch (IllegalStateException ex) {}
        
        // getValue() should throw an IllegalStateException
        try {
            it.getValue();
            fail();
        } catch (IllegalStateException ex) {}
        
        if (supportsSetValue() == false) {
            // setValue() should throw an UnsupportedOperationException/IllegalStateException
            try {
                it.setValue(addSetValues()[0]);
                fail();
            } catch (UnsupportedOperationException ex) {
            } catch (IllegalStateException ex) {}
        } else {
            // setValue() should throw an IllegalStateException
            try {
                it.setValue(addSetValues()[0]);
                fail();
            } catch (IllegalStateException ex) {}
        }
    }

    //-----------------------------------------------------------------------
    /**
     * Test that the full list iterator contract is correct.
     */
    public void testFullMapIterator() {
        if (supportsFullIterator() == false) {
            return;
        }

        MapIterator it = makeFullMapIterator();
        Map map = getMap();
        assertEquals(true, it.hasNext());
        
        assertEquals(true, it.hasNext());
        Set set = new HashSet();
        while (it.hasNext()) {
            // getKey
            Object key = it.next();
            assertSame("it.next() should equals getKey()", key, it.getKey());
            assertTrue("Key must be in map",  map.containsKey(key));
            assertTrue("Key must be unique", set.add(key));
            
            // getValue
            Object value = it.getValue();
            if (isGetStructuralModify() == false) {
                assertSame("Value must be mapped to key", map.get(key), value);
            }
            assertTrue("Value must be in map",  map.containsValue(value));

            verify();
        }
    }
    
    //-----------------------------------------------------------------------
    public void testMapIteratorSet() {
        if (supportsFullIterator() == false) {
            return;
        }

        Object newValue = addSetValues()[0];
        Object newValue2 = (addSetValues().length == 1 ? addSetValues()[0] : addSetValues()[1]);
        MapIterator it = makeFullMapIterator();
        Map map = getMap();
        Map confirmed = getConfirmedMap();
        assertEquals(true, it.hasNext());
        Object key = it.next();
        Object value = it.getValue();
        
        if (supportsSetValue() == false) {
            try {
                it.setValue(newValue);
                fail();
            } catch (UnsupportedOperationException ex) {}
            return;
        }
        Object old = it.setValue(newValue);
        confirmed.put(key, newValue);
        assertSame("Key must not change after setValue", key, it.getKey());
        assertSame("Value must be changed after setValue", newValue, it.getValue());
        assertSame("setValue must return old value", value, old);
        assertEquals("Map must contain key", true, map.containsKey(key));
        // test against confirmed, as map may contain value twice
        assertEquals("Map must not contain old value", 
            confirmed.containsValue(old), map.containsValue(old));
        assertEquals("Map must contain new value", true, map.containsValue(newValue));
        verify();
        
        it.setValue(newValue);  // same value - should be OK
        confirmed.put(key, newValue);
        assertSame("Key must not change after setValue", key, it.getKey());
        assertSame("Value must be changed after setValue", newValue, it.getValue());
        verify();
        
        it.setValue(newValue2);  // new value
        confirmed.put(key, newValue2);
        assertSame("Key must not change after setValue", key, it.getKey());
        assertSame("Value must be changed after setValue", newValue2, it.getValue());
        verify();
    }

    //-----------------------------------------------------------------------
    public void testRemove() { // override
        MapIterator it = makeFullMapIterator();
        Map map = getMap();
        Map confirmed = getConfirmedMap();
        assertEquals(true, it.hasNext());
        Object key = it.next();
        
        if (supportsRemove() == false) {
            try {
                it.remove();
                fail();
            } catch (UnsupportedOperationException ex) {
            }
            return;
        }
        
        it.remove();
        confirmed.remove(key);
        assertEquals(false, map.containsKey(key));
        verify();
        
        try {
            it.remove();  // second remove fails
        } catch (IllegalStateException ex) {
        }
        verify();
    }

    //-----------------------------------------------------------------------
    public void testMapIteratorSetRemoveSet() {
        if (supportsSetValue() == false || supportsRemove() == false) {
            return;
        }
        Object newValue = addSetValues()[0];
        MapIterator it = makeFullMapIterator();
        Map map = getMap();
        Map confirmed = getConfirmedMap();
        
        assertEquals(true, it.hasNext());
        Object key = it.next();
        
        it.setValue(newValue);
        it.remove();
        confirmed.remove(key);
        verify();
        
        try {
            it.setValue(newValue);
            fail();
        } catch (IllegalStateException ex) {}
        verify();
    }

    //-----------------------------------------------------------------------
    public void testMapIteratorRemoveGetKey() {
        if (supportsRemove() == false) {
            return;
        }
        MapIterator it = makeFullMapIterator();
        Map map = getMap();
        Map confirmed = getConfirmedMap();
        
        assertEquals(true, it.hasNext());
        Object key = it.next();
        
        it.remove();
        confirmed.remove(key);
        verify();
        
        try {
            it.getKey();
            fail();
        } catch (IllegalStateException ex) {}
        verify();
    }

    //-----------------------------------------------------------------------
    public void testMapIteratorRemoveGetValue() {
        if (supportsRemove() == false) {
            return;
        }
        MapIterator it = makeFullMapIterator();
        Map map = getMap();
        Map confirmed = getConfirmedMap();
        
        assertEquals(true, it.hasNext());
        Object key = it.next();
        
        it.remove();
        confirmed.remove(key);
        verify();
        
        try {
            it.getValue();
            fail();
        } catch (IllegalStateException ex) {}
        verify();
    }

}
