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

import java.util.function.Supplier;


/**
 * Few utility methods for working with nulls, booleans, etc
 */
@SuppressWarnings({
    "PMD.ShortVar", 
    "PMD.ShortMethodName"
})
public final class ValueUtils {
    
    private ValueUtils() { }

    /**
     * Checks if this value is exactly "true".
     * Returns false, if this value is "null", "false", or it isn't boolean at all.
     *
     * @param value value
     * @return boolean
     */
    public static boolean isTrue(Object value) {
        return (value instanceof Boolean) && (Boolean)value;
    }

    /**
     * Checks if this value is exactly "false".
     * Returns false, if this value is "null", "true", or it isn't boolean at all.
     *
     * @param value value
     * @return boolean
     */
    public static boolean isFalse(Object value) {
        return (value instanceof Boolean) && !(Boolean)value;
    }
    
    /**
     * Returns first non-null value or {@code null} if any value doesn't fit
     * @param values values
     * @param <T> T
     * @return value
     */
    @SafeVarargs
    public static <T> T or(T... values) {
        for(T value : values) { if(null != value) { return value; } }
        return null;
    }

    /**
     * Returns first non-null value or {@code null} if any value doesn't fit
     * @param a a
     * @param b b
     * @param <T> T
     * @return value
     */
    public static <T> T or(T a, T b) {
        return null != a ? a : b;
    }

    /**
     * Returns value generated by provided supplier.
     * If supplier returned "null", it returns "other"
     *
     * @param other other
     * @param supplier supplier
     * @param <T> T
     * @return value
     */
	public static <T> T eval(T other, Supplier<? extends T> supplier) {
		try {
			T s = supplier.get();
			if(s != null) {
				return s;
			}
		} catch(NullPointerException $0) { // NOPMD
			// do nothing
		}
		return other;
	}

}
