package org.xbib.datastructures.immutable.order;

import java.util.List;
import org.xbib.datastructures.immutable.ImmutableMap;
import static org.xbib.datastructures.immutable.ImmutableMap.indexMap;

/**
 * An ordering that compares objects according to a given order.
 */
final class ExplicitOrdering<T> extends Ordering<T> {
    final ImmutableMap<T, Integer> rankMap;

    ExplicitOrdering(List<T> valuesInOrder) {
        this(indexMap(valuesInOrder));
    }

    ExplicitOrdering(ImmutableMap<T, Integer> rankMap) {
        this.rankMap = rankMap;
    }

    @Override
    public int compare(T left, T right) {
        return rank(left) - rank(right); // safe because both are nonnegative
    }

    private int rank(T value) {
        Integer rank = rankMap.get(value);
        if (rank == null) {
            throw new IncomparableValueException(value);
        }
        return rank;
    }

    @Override
    public boolean equals(Object object) {
        if (object instanceof ExplicitOrdering<?> that) {
            return this.rankMap.equals(that.rankMap);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return rankMap.hashCode();
    }

    @Override
    public String toString() {
        return "Ordering.explicit(" + rankMap.keySet() + ")";
    }

}
