package org.xbib.datastructures.immutable.order;

import java.util.Objects;

/**
 * An ordering that uses the natural order of the values.
 */
@SuppressWarnings("unchecked")
final class NaturalOrdering extends Ordering<Comparable<?>> {
    static final NaturalOrdering INSTANCE = new NaturalOrdering();

    private transient Ordering<Comparable<?>> nullsFirst;
    private transient Ordering<Comparable<?>> nullsLast;

    private NaturalOrdering() {
    }

    @Override
    public int compare(Comparable<?> left, Comparable<?> right) {
        Objects.requireNonNull(left);
        Objects.requireNonNull(right);
        return ((Comparable<Object>) left).compareTo(right);
    }

    @Override
    public <S extends Comparable<?>> Ordering<S> nullsFirst() {
        Ordering<Comparable<?>> result = nullsFirst;
        if (result == null) {
            result = nullsFirst = super.nullsFirst();
        }
        return (Ordering<S>) result;
    }

    @Override
    public <S extends Comparable<?>> Ordering<S> nullsLast() {
        Ordering<Comparable<?>> result = nullsLast;
        if (result == null) {
            result = nullsLast = super.nullsLast();
        }
        return (Ordering<S>) result;
    }

    @Override
    public <S extends Comparable<?>> Ordering<S> reverse() {
        return (Ordering<S>) ReverseNaturalOrdering.INSTANCE;
    }

    @Override
    public String toString() {
        return "Ordering.natural()";
    }

}
