package stexfires.core.modifier;

import stexfires.core.Record;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * @author Mathias Kalb
 * @since 0.1
 */
public class UnaryGroupModifier<T extends Record> extends GroupModifier<T, T> implements UnaryRecordStreamModifier<T> {

    public UnaryGroupModifier(Function<? super T, ?> groupByClassifier,
                              Function<List<T>, ? extends T> aggregateFunction) {
        super(groupByClassifier, aggregateFunction);
    }

    public UnaryGroupModifier(Function<? super T, ?> groupByClassifier,
                              Predicate<List<? super T>> havingPredicate,
                              Function<List<T>, ? extends T> aggregateFunction) {
        super(groupByClassifier, havingPredicate, aggregateFunction);
    }

    public static <T extends Record> UnaryGroupModifier first(Function<? super T, ?> groupByClassifier) {
        // The list contains always at least one record.
        Function<List<T>, T> aggregateFunction = list -> list.get(0);
        return new UnaryGroupModifier<>(groupByClassifier, aggregateFunction);
    }

    public static <T extends Record> UnaryGroupModifier last(Function<? super T, ?> groupByClassifier) {
        // The list contains always at least one record.
        Function<List<T>, T> aggregateFunction = list -> list.get(list.size() - 1);
        return new UnaryGroupModifier<>(groupByClassifier, aggregateFunction);
    }

    public static <T extends Record> UnaryGroupModifier max(Function<? super T, ?> groupByClassifier,
                                                            Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        // The list contains always at least one record.
        @SuppressWarnings("OptionalGetWithoutIsPresent")
        Function<List<T>, T> aggregateFunction = list -> list.stream().max(comparator).get();
        return new UnaryGroupModifier<>(groupByClassifier, aggregateFunction);
    }

    public static <T extends Record> UnaryGroupModifier min(Function<? super T, ?> groupByClassifier,
                                                            Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        // The list contains always at least one record.
        @SuppressWarnings("OptionalGetWithoutIsPresent")
        Function<List<T>, T> aggregateFunction = list -> list.stream().min(comparator).get();
        return new UnaryGroupModifier<>(groupByClassifier, aggregateFunction);
    }

}

@@ -951,16 +951,19 @@
 Modifier
+%3CT%3E
  first(F
@@ -997,32 +997,32 @@
 ByClassifier) %7B%0A
-
         // The l
@@ -1273,16 +1273,19 @@
 Modifier
+%3CT%3E
  last(Fu
@@ -1608,16 +1608,19 @@
 Modifier
+%3CT%3E
  max(Fun
@@ -1650,32 +1650,35 @@
 upByClassifier,%0A
+   
                 
@@ -2150,16 +2150,19 @@
 Modifier
+%3CT%3E
  min(Fun
@@ -2192,32 +2192,35 @@
 upByClassifier,%0A
+   
                 

Fix generics