package io.delphiplatform.api.util;

import java.util.Comparator;
import java.util.function.Function;

import io.delphiplatform.api.v3.model.SortOrder;

import static java.util.Comparator.comparing;
import static java.util.Comparator.naturalOrder;
import static java.util.Comparator.reverseOrder;

public class ComparatorInfo<T> {

    private final Function<T, Comparable<? extends Comparable>> keyExtractor;
    private final Function<Comparator<? extends Comparable>, Comparator<? extends Comparable>> guardComparatorFactory;

    public ComparatorInfo(Function<T, Comparable<? extends Comparable>> keyExtractor,
        Function<Comparator<? extends Comparable>, Comparator<? extends Comparable>> guardComparatorFactory) {

        this.keyExtractor = keyExtractor;
        this.guardComparatorFactory = guardComparatorFactory;
    }

    public static <T> ComparatorInfo<T> comparatorInfo(Function<T, Comparable<? extends Comparable>> keyExtractor) {
        return new ComparatorInfo<>(keyExtractor, Comparator::nullsLast);
    }

    public static <T> ComparatorInfo<T> comparatorInfo(Function<T, Comparable<? extends Comparable>> keyExtractor,
        Function<Comparator<? extends Comparable>, Comparator<? extends Comparable>> guardComparatorFactory) {
        return new ComparatorInfo<>(keyExtractor, guardComparatorFactory);
    }

    public Comparator<T> getComparator(SortOrder sortOrder) {
        Comparator comparator = SortOrder.DESC.equals(sortOrder) ?
            reverseOrder() :
            naturalOrder();

        return comparing(keyExtractor, guardComparatorFactory.apply(comparator));
    }
}
