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

import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.SortedSet;
import javax.annotation.Resource;
import net.ranides.assira.collection.maps.IntMap.IntEntry;
import net.ranides.assira.collection.maps.IntSortedMap;
import net.ranides.assira.collection.suite.IteratorTester;
import net.ranides.assira.collection.suite.sets.SetTester;
import static net.ranides.assira.junit.NewAssert.assertThrows;
import net.ranides.assira.test.TMap;
import net.ranides.assira.test.TMap.TItem;
import net.ranides.assira.test.TMap.TItems;
import static org.junit.Assert.assertEquals;
import net.ranides.assira.junit.TestContract;
import static org.junit.Assert.assertEquals;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public final class IntSortedMapTester<V> {
    
    @Resource(name = "map!")
    private TMap<Integer,V> $var;

    @TestContract
    public void basicKeys_Head(IntSortedMap<V> target) {
        SetTester.assertHead($var.keys(), target.keySet(), $var.list().keys());
        $var.list(4, 7, 5, 3, 6).into(target);
        SetTester.assertHead($var.keys(), target.keySet(), $var.list(3, 4, 5, 6, 7).keys());
    }
    
    @TestContract
    public void basicKeys_Tail(IntSortedMap<V> target) {
        SetTester.assertTail($var.keys(), target.keySet(), $var.list().keys());
        $var.list(4, 7, 5, 3, 6).into(target);
        SetTester.assertTail($var.keys(), target.keySet(), $var.list(3, 4, 5, 6, 7).keys());
    }
    
    @TestContract
    public void basicKeys_Sub(IntSortedMap<V> target) {
        SetTester.assertTail($var.keys(), target.keySet(), $var.list().keys());
        $var.list(4, 7, 5, 3, 6).into(target);
        SetTester.assertTail($var.keys(), target.keySet(), $var.list(3, 4, 5, 6, 7).keys());
    }
    
    @TestContract
    public void basicEntries_Head(IntSortedMap<V> target) {
        SetTester.assertHead($var.entriesInt(), target.fastEntrySet(), $var.list().entriesInt());
        $var.list(4, 7, 5, 3, 6).into(target);
        SetTester.assertHead($var.entriesInt(), target.fastEntrySet(), $var.list(3, 4, 5, 6, 7).entriesInt());
    }
    
    @TestContract
    public void basicEntries_Tail(IntSortedMap<V> target) {
        SetTester.assertTail($var.entriesInt(), target.fastEntrySet(), $var.list().entriesInt());
        $var.list(4, 7, 5, 3, 6).into(target);
        SetTester.assertTail($var.entriesInt(), target.fastEntrySet(), $var.list(3, 4, 5, 6, 7).entriesInt());
    }
    
    @TestContract
    public void basicEntries_Sub(IntSortedMap<V> target) {
        SetTester.assertSub($var.entriesInt(), target.fastEntrySet(), $var.list().entriesInt());
        $var.list(4, 7, 5, 3, 6).into(target);
        SetTester.assertSub($var.entriesInt(), target.fastEntrySet(), $var.list(3, 4, 5, 6, 7).entriesInt());
    }
    
    @SuppressWarnings("unchecked")
    @TestContract
    public void basicIterator(IntSortedMap<V> target) {
        TItems<Integer,V> list1 = $var.list();
        TItems<Integer,V> list2 = $var.list(3, 4, 5, 6, 7);
        
        IteratorTester.orderIterator(target.keySet().iterator(), 0, list1.keys());
        IteratorTester.orderIterator(target.fastEntrySet().iterator(), 0, list1.entriesInt());
        IteratorTester.orderIterator((ListIterator)target.values().iterator(), 0, list1.values());
        
        $var.list(4, 7, 5, 3, 6).into(target);
        
        IteratorTester.orderIterator(target.keySet().iterator(), 0, list2.keys());
        IteratorTester.orderIterator(target.fastEntrySet().iterator(), 0, list2.entriesInt());
        IteratorTester.orderIterator((ListIterator)target.values().iterator(), 0, list2.values());
    }
    
    @SuppressWarnings("unchecked")
    @TestContract
    public void basicIteratorFrom(IntSortedMap<V> target) {
        TItems<Integer,V> list1 = $var.list();
        TItems<Integer,V> list2 = $var.list(3, 4, 5, 6, 7);
        TItem<Integer,V> item = $var.item(4);
        
        IteratorTester.orderIterator(target.keySet().iterator(item.key()), 0, list1.keys());
        IteratorTester.orderIterator(target.fastEntrySet().iterator(item.entryInt()), 0, list1.entriesInt());
        
        $var.list(4, 7, 5, 3, 6).into(target);
        
        IteratorTester.orderIterator(target.keySet().iterator(item.key()), 1, list2.keys());
        IteratorTester.orderIterator(target.fastEntrySet().iterator(item.entryInt()), 1, list2.entriesInt());
    }
    
    @SuppressWarnings("unchecked")
    @TestContract
    public void basicSubmapIteratorFrom(IntSortedMap<V> target) {
        TItems<Integer,V> list = $var.list(3, 4, 5, 6, 7);
        TItem<Integer,V> item = $var.item(4);

        $var.list(4, 7, 5, 3, 6, 1, 8).into(target);
        IntSortedMap<V> map = target.subMap($var.item(1).keyInt(), $var.item(8).keyInt());
        IteratorTester.subIterator(map.keySet().iterator(item.key()), 2, list.keys());
        IteratorTester.subIterator(map.fastEntrySet().iterator(item.entryInt()), 2, list.entriesInt());
    }
    
    @TestContract
    public void basicBounds_IntEntrySet(IntSortedMap<V> target) {
        SortedSet<IntEntry<V>> set = target.fastEntrySet();
        assertThrows(NoSuchElementException.class, ()->
            set.first()
        );
        assertThrows(NoSuchElementException.class, ()->
            set.last()
        );
        $var.list(2,5,3,1,4).into(target);
        assertEquals($var.item(1).entry(), set.first());
        assertEquals($var.item(5).entry(), set.last());
    }
    
}
