/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.collection.suite;

import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import static net.ranides.assira.junit.NewAssert.*;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public final class IteratorTester {
    
    private IteratorTester() { }
    
    public static <T> void basicIterator(Iterator<T> iterator, int index, T[] content) {
        for (int i=index; i<content.length; i++) {
            assertTrue(iterator.hasNext());
            assertEquals(content[i], iterator.next());
        }
        assertFalse(iterator.hasNext());
        assertThrows(NoSuchElementException.class, ()->
            iterator.next()
        );
    }
    
    public static <T> void orderIterator(ListIterator<T> iterator, int index, T[] content) {
        assertEquals(index>0, iterator.hasPrevious());
        assertEquals(content.length>0, iterator.hasNext());
        
        for (int i=index; i<content.length; i++) {
            checkIndex(iterator, i-index);
            assertTrue(iterator.hasNext());
            assertEquals(content[i], iterator.next());
        }
        
        assertFalse(iterator.hasNext());
        assertEquals(content.length>0, iterator.hasPrevious());
        assertThrows(NoSuchElementException.class, ()->
            iterator.next()
        );
        
        for (int i=content.length-1; i>=0; i--) {
            assertTrue(iterator.hasPrevious());
            assertEquals(content[i], iterator.previous());
            checkIndex(iterator, i-index);
        }
        
        assertEquals(content.length>0, iterator.hasNext());
        assertFalse(iterator.hasPrevious());
        assertThrows(NoSuchElementException.class, ()->
            iterator.previous()
        );
    }
    
    public static <T> void listIterator(ListIterator<T> iterator, int index, T[] content) {
        assertEquals(index>0, iterator.hasPrevious());
        assertEquals(content.length>0, iterator.hasNext());
        
//		System.err.printf("DATA = [%d] %s %n", index, Arrays.toString(content));
//		System.err.printf(">>>>>>%n");
        for (int i=index; i<content.length; i++) {
            checkIndex(iterator, i);
            assertTrue(iterator.hasNext());
            assertEquals(content[i], iterator.next());
        }
//        System.err.printf("    * %d / %d%n", iterator.previousIndex(), iterator.nextIndex());
        assertFalse(iterator.hasNext());
//		System.err.printf("    * %d / %d%n", iterator.previousIndex(), iterator.nextIndex());
        assertEquals(content.length>0, iterator.hasPrevious());
//		System.err.printf("    * %d / %d%n", iterator.previousIndex(), iterator.nextIndex());
        assertThrows(NoSuchElementException.class, ()->
            iterator.next()
        );
//		System.err.printf("    * %d / %d%n", iterator.previousIndex(), iterator.nextIndex());
//        System.err.printf("------------%n");
		
        for (int i=content.length-1; i>=0; i--) {
            assertTrue(iterator.hasPrevious());
            assertEquals(content[i], iterator.previous());
            checkIndex(iterator, i);
        }
//        System.err.printf("<<<<<<%n");
        assertEquals(content.length>0, iterator.hasNext());
        assertFalse(iterator.hasPrevious());
        assertThrows(NoSuchElementException.class, ()->
            iterator.previous()
        );
    }
    
    public static <T> void subIterator(ListIterator<T> iterator, int index, T[] content) {
        for (int i=index; i<content.length; i++) {
            checkIndex(iterator, i-index);
            assertTrue(iterator.hasNext());
            assertEquals(content[i], iterator.next());
        }
        for (int i=content.length-1; i>=0; i--) {
            assertTrue(iterator.hasPrevious());
            assertEquals(content[i], iterator.previous());
            checkIndex(iterator, i-index);
        }
    }
    
    private static void checkIndex(ListIterator<?> iterator, int current) {
//		System.err.printf("    - [%d]   %d  -> %d%n", current, iterator.previousIndex(), iterator.nextIndex());
        assertEquals(current, iterator.nextIndex());
        assertEquals(current-1, iterator.previousIndex());
    }

}
