/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.enums;

/**
 * Wyjątek rzucany przez metodę {@link #assertUnique} - pozwala ustalić,
 * która wartość jest zduplikowana, i z jakimi stałymi w typie wyliczeniowym
 * jest powiązana.
 */
public final class EnumDuplicateError extends AssertionError {
    private final String name;
    private final Object value;
    private final Enum<?> first;
    private final Enum<?> second;

    <T extends Enum<T>> EnumDuplicateError(String property, Object value, T first, T second) {
        this.name = property;
        this.value = value;
        this.first = first;
        this.second = second;
    }

    /**
     * Zwraca klasę typu wyliczeniowego, który był sprawdzany pod kątem unikalności.
     * @return
     */
    public Class<?> type() {
        return first.getDeclaringClass();
    }

    /**
     * Zwraca wartość, która jest przypisana do więcej niż jednej stałej {@code enum}
     * @return
     */
    public Object value() {
        return value;
    }

    /**
     * Zwraca nazwę atrybuty JavaBeans, który był sprawdzany pod kątem unikalności.
     * @return
     */
    public String name() {
        return name;
    }

    /**
     * Zwraca pierwszą stałą, która posiada atrybut o zduplikowanej wartości.
     * @return
     */
    public Enum<?> first() {
        return first;
    }

    /**
     * Zwraca drugą stałą, która posiada atrybut o zduplikowanej wartości.
     * @return
     */
    public Enum<?> second() {
        return second;
    }

    @Override
    public String toString() {
        // Enum.property (FIRST : SECOND) = value
        return String.format("Duplicated property value: %s.%s (%s : %s) = %s", type().getName(), name, first.name(), second.name(), value);
    }
    
}
