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.function.Consumer;
import java.util.function.Predicate;

/**
 * This is internal utility class not supposed to use by clients.
 * It has default implementations of sequential query operations for arrays.
 *
 * Those methods should not be called directly, but by "BaseArray" facade.
 */
@UtilityClass
@SuppressWarnings("MissingJavadoc")
public class BaseArraySequential {

    public static <T> void forEach(T[] array, Consumer<? super T> consumer) {
        for (T v : array) {
            consumer.accept(v);
        }
    }

    public static <T> void forEach(T[] array, int begin, int end, Consumer<? super T> consumer) {
        for (int index = begin; index < end; index++) {
            consumer.accept(array[index]);
        }
    }

    public static <T> void forEach(T[] array, Consumers.EachConsumer<? super T> consumer) {
        forEach(array, 0, array.length, consumer);
    }

    public static <T> void forEach(T[] array, int begin, int end, Consumers.EachConsumer<? super T> consumer) {
        for (int index = begin; index < end; index++) {
            consumer.accept(index-begin, array[index]);
        }
    }

    public static <T> boolean whileEach(T[] array, Predicate<? super T> consumer) {
        for (T a : array) {
            if (!consumer.test(a)) {
                return false;
            }
        }
        return true;
    }

    public static <T> boolean whileEach(T[] array, int begin, int end, Predicate<? super T> consumer) {
        for (int index = begin; index < end; index++) {
            if(!consumer.test(array[index])) {
                return false;
            }
        }
        return true;
    }

    public static <T> boolean whileEach(T[] array, Predicates.EachPredicate<? super T> consumer) {
        return whileEach(array, 0, array.length, consumer);
    }

    public static <T> boolean whileEach(T[] array, int begin, int end, Predicates.EachPredicate<? super T> consumer) {
        for (int index = begin; index < end; index++) {
            if(!consumer.test(index-begin, array[index])) {
                return false;
            }
        }
        return true;
    }
}
