package net.ranides.assira.collection.query.base;

import net.ranides.test.CQueryAssert;
import org.junit.Assert;
import org.junit.Test;

import net.ranides.assira.collection.lists.IntRange;
import net.ranides.assira.collection.query.CQuery;

import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.*;

public class CQListTest {

    @Test
    public void testLimitList() {
        List<Integer> input = Arrays.asList(7, 6, 2, 3, 4, 9, 2, 5, 1, 6, 7, 8, 4);

        CQueryAssert.assertEquals(Arrays.asList(7,6,2,3), CQuery.from().list(input).limit(4));
        CQueryAssert.assertEquals(Arrays.asList(2,3,4,9), CQuery.from().list(input).skip(2).limit(4));
        CQueryAssert.assertEquals(Arrays.asList(2,3), CQuery.from().list(input).limit(4).skip(2));

        CQueryAssert.assertEquals(Arrays.asList(2,3), CQuery.from().list(input).limit(4).slice(2,4));
        CQueryAssert.assertEquals(Arrays.asList(2,3), CQuery.from().list(input).limit(4).slice(2,6));

        List<Integer> out3 = new ArrayList<>();
        assertEquals(18, CQuery.from().list(input).skip(2).limit(4).onEach(v -> out3.add(v)).reduce(Integer::sum).intValue());
        assertEquals(Arrays.asList(2,3,4,9), out3);

        List<String> out4 = new ArrayList<>();
        assertEquals(64, CQuery.from().list(input)
            .onEach((i,v) -> out4.add(i+"#"+v))
            .reduce(Integer::sum).intValue()
        );
        assertEquals(Arrays.asList("0#7", "1#6", "2#2", "3#3", "4#4", "5#9", "6#2", "7#5", "8#1", "9#6", "10#7", "11#8", "12#4"), out4);

        List<String> out5 = new ArrayList<>();
        assertEquals(18, CQuery.from().list(input)
            .limit(4).onEach((i, v) -> out5.add(i + "#" + v))
            .reduce(Integer::sum).intValue()
        );
        assertEquals(Arrays.asList("0#7", "1#6", "2#2", "3#3"), out5);

        List<String> out6 = new ArrayList<>();
        assertEquals(18, CQuery.from().list(input)
            .onEach((i, v) -> out6.add(i + "#" + v)).limit(4)
            .reduce(Integer::sum).intValue()
        );

        assertEquals(Arrays.asList("0#7", "1#6", "2#2", "3#3"), out6);
    }

    @Test
    public void fetch() {
        CQList<Integer> query = new CQList<>(Arrays.asList(1, 2, 3, 4, 5));

        Assert.assertSame(query, query.fetch());
        Assert.assertSame(query, query.prefetch());
        Assert.assertSame(query, query.cache(Paths.get("abc")));
    }

    @Test
    public void paralellEach() {
        List<Integer> range = new ArrayList<>(new IntRange(0, 50));
        CQueryAssert.assertOrderedParallel(new CQList<>(range));
    }

}