// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core;

import java.util.Iterator;
import javax.annotation.Nullable;
import java.util.function.Function;
import java.util.Collection;
import java.util.function.BiPredicate;
import java.util.Comparator;
import javax.annotation.Nonnull;

public enum NameMatching
{
    EXACT((s1, s2) -> s1.equals(s2) ? 0 : Integer.MIN_VALUE, String::equals), 
    EXACT_IGNORE_CASE((s1, s2) -> s1.equalsIgnoreCase(s2) ? 0 : Integer.MIN_VALUE, String::equalsIgnoreCase), 
    STARTS_WITH((s1, s2) -> s1.startsWith(s2) ? (s1.length() - s2.length()) : Integer.MIN_VALUE, String::equals), 
    STARTS_WITH_IGNORE_CASE((s1, s2) -> s1.toLowerCase().startsWith(s2.toLowerCase()) ? (s1.length() - s2.length()) : Integer.MIN_VALUE, String::equalsIgnoreCase);
    
    @Nonnull
    public static NameMatching DEFAULT;
    private final Comparator<String> comparator;
    private final BiPredicate<String, String> equality;
    
    private NameMatching(final Comparator<String> comparator, final BiPredicate<String, String> equality) {
        this.comparator = comparator;
        this.equality = equality;
    }
    
    public Comparator<String> getComparator() {
        return this.comparator;
    }
    
    @Nullable
    public <T> T find(@Nonnull final Collection<T> players, final String value, @Nonnull final Function<T, String> getter) {
        return find(players, value, getter, this.comparator, this.equality);
    }
    
    @Nullable
    public static <T> T find(@Nonnull final Collection<T> players, final String value, @Nonnull final Function<T, String> getter, @Nonnull final Comparator<String> comparator, @Nonnull final BiPredicate<String, String> equality) {
        T closest = null;
        int highestScore = Integer.MIN_VALUE;
        for (final T player : players) {
            final String name = getter.apply(player);
            if (equality.test(name, value)) {
                return player;
            }
            final int comparison = comparator.compare(name, value);
            if (comparison <= highestScore) {
                continue;
            }
            highestScore = comparison;
            closest = player;
        }
        if (highestScore == Integer.MIN_VALUE) {
            return null;
        }
        return closest;
    }
    
    static {
        NameMatching.DEFAULT = NameMatching.STARTS_WITH_IGNORE_CASE;
    }
}
