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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import net.ranides.assira.generic.Function;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
@SuppressWarnings("UnnecessaryUnboxing")
public class CollectionUtilsTest {
    
    public CollectionUtilsTest() {
    }

    @Test
    public void testFirst() {
        assertEquals(1, CollectionUtils.first(Arrays.asList(1,2,3)).intValue());
        assertEquals(1, CollectionUtils.first(Arrays.asList(1)).intValue());
        assertNull(CollectionUtils.first(Arrays.asList()));
        assertNull(CollectionUtils.first((List<?>)null));
        
        assertEquals( 1L, CollectionUtils.first(Arrays.<Object>asList(0f, 7, 1L), Long.class).longValue());
        assertEquals( 7L, CollectionUtils.first(Arrays.<Object>asList(7L, 0f, 7, 1L), Long.class).longValue());
        assertEquals( 7L, CollectionUtils.first(Arrays.<Object>asList(7L, 1L), Long.class).longValue());
        assertEquals( 7L, CollectionUtils.first(Arrays.<Object>asList(7L), Long.class).longValue());
        assertNull( CollectionUtils.first(Arrays.<Object>asList(0f, 7), Long.class));
        assertNull( CollectionUtils.first(Arrays.<Object>asList(), Long.class));
        assertNull( CollectionUtils.first(null, Long.class));
    }
    
    @Test
    public void testLast() {
        assertEquals(3, CollectionUtils.last(Arrays.asList(1,2,3)).intValue());
        assertEquals(1, CollectionUtils.last(Arrays.asList(1)).intValue());
        assertNull(CollectionUtils.last(Arrays.asList()));
        assertNull(CollectionUtils.last((Collection<?>)null));
        
        assertEquals( 1L, CollectionUtils.last(Arrays.<Object>asList(0f, 7, 1L), Long.class).longValue());
        assertEquals( 1L, CollectionUtils.last(Arrays.<Object>asList(7L, 0f, 7, 1L), Long.class).longValue());
        assertEquals( 1L, CollectionUtils.last(Arrays.<Object>asList(7L, 1L), Long.class).longValue());
        assertEquals( 7L, CollectionUtils.last(Arrays.<Object>asList(7L), Long.class).longValue());
        assertNull( CollectionUtils.last(Arrays.<Object>asList(0f, 7), Long.class));
        assertNull( CollectionUtils.last(Arrays.<Object>asList(), Long.class));
        assertNull( CollectionUtils.last(null, Long.class));
    }
    
    @Test
    public void testGet() {
        assertNull( CollectionUtils.get(null, 4) );
        assertNull( CollectionUtils.get(null, 0) );
        assertNull( CollectionUtils.get(Arrays.asList(1,2,3), 6) );
        assertNull( CollectionUtils.get(Arrays.asList(1,2,3), -2) );
        
        assertEquals( 1, CollectionUtils.get(Arrays.asList(1,2,3), 0).intValue() );
        assertEquals( 3, CollectionUtils.get(Arrays.asList(1,2,3), 2).intValue() );
        
        assertEquals(99, CollectionUtils.get(null, 4, 99).intValue() );
        assertEquals(99, CollectionUtils.get(null, 0, 99).intValue() );
        assertEquals(99, CollectionUtils.get(Arrays.asList(1,2,3), 6, 99).intValue() );
        assertEquals(99, CollectionUtils.get(Arrays.asList(1,2,3), -2, 99).intValue() );
        
        assertEquals( 1, CollectionUtils.get(Arrays.asList(1,2,3), 0, 99).intValue() );
        assertEquals( 3, CollectionUtils.get(Arrays.asList(1,2,3), 2, 99).intValue() );
    }
    
    @Test
    public void testSize() {
        assertEquals(0, CollectionUtils.size((Collection<?>)null));
        assertEquals(0, CollectionUtils.size(Collections.emptyList()));
        assertEquals(1, CollectionUtils.size(Arrays.asList(1)));
        assertEquals(3, CollectionUtils.size(Arrays.asList(1,1,1)));
        
        assertTrue(CollectionUtils.isEmpty(null));
        assertTrue(CollectionUtils.isEmpty(Collections.emptyList()));
        assertFalse(CollectionUtils.isEmpty(Arrays.asList(1)));
        assertFalse(CollectionUtils.isEmpty(Arrays.asList(1,1,1)));
        
        assertTrue( CollectionUtils.equalSize(null, null) );
        assertTrue( CollectionUtils.equalSize(Collections.emptyList(), null) );
        assertTrue( CollectionUtils.equalSize(null, Collections.emptyList()) );
        assertTrue( CollectionUtils.equalSize(Arrays.asList(1,1,1), Arrays.asList(1,3,4)) );
        
        assertFalse( CollectionUtils.equalSize(Arrays.asList(1,1,1), Arrays.asList(1,1)) );
        assertFalse( CollectionUtils.equalSize(null, Arrays.asList(1,1)) );
        assertFalse( CollectionUtils.equalSize(Arrays.asList(1,1),null) );
    }

    @Test
    public void testClip() {
        assertEquals(Arrays.asList(1,2,3), CollectionUtils.clip(Arrays.asList(1,2,3), 5));
        assertEquals(Arrays.asList(1,2,3), CollectionUtils.clip(Arrays.asList(1,2,3), 3));
        
        assertEquals(SetUtils.asHashSet(1,2), CollectionUtils.clip(Arrays.asList(1,2,3), 2));
        assertEquals(SetUtils.asHashSet(1), CollectionUtils.clip(Arrays.asList(1,2,3), 1));
        assertEquals(SetUtils.asHashSet(), CollectionUtils.clip(Arrays.asList(1,2,3), 0));
        
        List<Integer> list = new ArrayList<>(Arrays.asList(1,2,3,4,5));
        Iterator<Integer> iterator = CollectionUtils.clip(list, 3).iterator();
        iterator.next();
        iterator.next();
        iterator.remove();
        assertEquals(Arrays.asList(1,3,4,5), list);
    }
    
    @Test
    public void testAdapt() {
        Collection<String> set1 = CollectionUtils.adapt(SetUtils.asHashSet(1,2,3,4), new Function<String, Integer>() {
            @Override
            public String apply(Integer source) {
                return String.valueOf(source);
            }
        });
        assertEquals(4, set1.size());
        assertEquals(SetUtils.asHashSet("1","2","3","4"), set1);
        
        Iterator<String> iterator = CollectionUtils.adapt(Arrays.asList(1,2,3,4).iterator(), new Function<String, Integer>() {
            @Override
            public String apply(Integer source) {
                return String.valueOf(source);
            }
        });
        assertEquals(Arrays.asList("1","2","3","4"), ListUtils.asList(iterator));
    }
    
    @Test
    public void testAsCollection() {
        Collection<Integer> collection = CollectionUtils.asCollection(4, Arrays.asList(1,2,3,4));
        assertEquals(4, collection.size());
        assertEquals("[1, 2, 3, 4]", collection.toString());
    }
    
}
