package net.ranides.assira.collection.iterators;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import net.ranides.assira.collection.lists.IntRange;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;

import net.ranides.assira.collection.query.support.BaseSpliterator;

import java.util.Arrays;
import java.util.List;


public class SpliteratorUtilsTest {

    @Ignore("manual")
    @Test
    public void forEach1() {
        List<Integer> list = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);

        BaseSpliterator.forEach(list.spliterator(), true, (i,v) -> {
            System.err.println(Thread.currentThread() + "   " + i + " = " + v);
        });
    }

    @Ignore("manual")
    @Test
    public void whileEach1() {
        List<Integer> list = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32);

        BaseSpliterator.whileEach(list.spliterator(), true, (i,v) -> {
            System.err.println(Thread.currentThread() + "   " + i + " = " + v);
            return i != 1 && i!=9 && i!=17;
        });
    }

    @Ignore("manual")
    @Test
    public void limitThreads() {
        Set<Integer> set = new HashSet<>(new IntRange(1, 100));
        SpliteratorUtils.limit(set.parallelStream(), v -> v < 50).forEach(v -> {
            System.err.println(Thread.currentThread().getName() + "   "+ v);
        });
    }

    @Test
    public void limit() {
        ArrayList<Integer> list = new ArrayList<>(new IntRange(1, 100));
        Set<Integer> set = new HashSet<>(new IntRange(1, 100));

        ConcurrentHashMap<Integer, Boolean> out1 = new ConcurrentHashMap<>();
        SpliteratorUtils.limit(list.stream(), v -> v != 50).forEach(v -> out1.put(v, true));

        ConcurrentHashMap<Integer, Boolean> out2 = new ConcurrentHashMap<>();
        SpliteratorUtils.limit(list.stream(), v -> v != 50).forEach(v -> out2.put(v, true));

        ConcurrentHashMap<Integer, Boolean> out3 = new ConcurrentHashMap<>();
        SpliteratorUtils.limit(set.parallelStream(), v -> v != 50).forEach(v -> out3.put(v, true));

        Set<Integer> out4 = SpliteratorUtils.limit(set.parallelStream(), v -> v != 50).collect(Collectors.toSet());

        Set<Integer> out5 = SpliteratorUtils.limit(IntStream.rangeClosed(1, 100).boxed(), v -> v != 50).collect(Collectors.toSet());

        Set<Integer> out6 = SpliteratorUtils.limit(IntStream.rangeClosed(1, 100).boxed().parallel(), v -> v != 50).collect(Collectors.toSet());

        Set<Integer> expected = new TreeSet<>(new IntRange(1, 50));

        Assert.assertEquals(expected, new TreeSet<>(out1.keySet()));
        Assert.assertEquals(expected, new TreeSet<>(out2.keySet()));
        Assert.assertEquals(expected, new TreeSet<>(out3.keySet()));
        Assert.assertEquals(expected, out4);
        Assert.assertEquals(expected, out5);
        Assert.assertEquals(expected, out6);
    }
}