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

import lombok.experimental.UtilityClass;

import net.ranides.assira.functional.Consumers;
import net.ranides.assira.functional.Predicates;

import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
 * This is internal utility class not supposed to use by clients.
 * It has default implementations of query operations using only Spliterator contract.
 *
 * It is almost complete facade: most of the time it delegates work to BaseSpliteratorParallel or BaseSpliteratorSequential.
 */
@UtilityClass
@SuppressWarnings("MissingJavadoc")
public class BaseSpliterator {

    public static <T> void forEach(Spliterator<T> that, boolean paralell, Consumer<? super T> consumer) {
        if(paralell) {
            BaseSpliteratorParalell.forEach(that, consumer);
        } else {
            BaseSpliteratorSequential.forEach(that, consumer);
        }
    }

    public static <T> void forEach(Spliterator<T> that, boolean paralell, Consumers.EachConsumer<? super T> consumer) {
        if(paralell) {
            BaseSpliteratorParalell.forEach(that, consumer);
        } else {
            BaseSpliteratorSequential.forEach(that, consumer);
        }
    }

    public static <T> boolean whileEach(Spliterator<T> that, boolean paralell, Predicate<? super T> consumer) {
        if(paralell) {
            return BaseSpliteratorParalell.whileEach(that, consumer);
        } else {
            return BaseSpliteratorSequential.whileEach(that, consumer);
        }
    }

    public static <T> boolean whileEach(Spliterator<T> that, boolean paralell, Predicates.EachPredicate<? super T> consumer) {
        if(paralell) {
            return BaseSpliteratorParalell.whileEach(that, consumer);
        } else {
            return BaseSpliteratorSequential.whileEach(that, consumer);
        }
    }

    public static <T> int size(Spliterator<T> that, boolean paralell) {
        if(paralell) {
            return BaseSpliteratorParalell.size(that);
        } else {
            return BaseSpliteratorSequential.size(that);
        }
    }

}
