package org.xbib.datastructures.immutable.order;

import java.util.Objects;
import java.util.function.Function;

/**
 * An ordering that orders elements by applying an order to the result of a function on those
 * elements.
 */
final class ByFunctionOrdering<F, T> extends Ordering<F> {
    final Function<F, ? extends T> function;
    final Ordering<T> ordering;

    ByFunctionOrdering(Function<F, ? extends T> function, Ordering<T> ordering) {
        this.function = Objects.requireNonNull(function);
        this.ordering = Objects.requireNonNull(ordering);
    }

    @Override
    public int compare(F left, F right) {
        return ordering.compare(function.apply(left), function.apply(right));
    }

    @Override
    public boolean equals(Object object) {
        if (object == this) {
            return true;
        }
        if (object instanceof ByFunctionOrdering<?, ?> that) {
            return this.function.equals(that.function) && this.ordering.equals(that.ordering);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(function, ordering);
    }

    @Override
    public String toString() {
        return ordering + ".onResultOf(" + function + ")";
    }
}
