// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.common.util;

import java.util.function.Supplier;
import java.util.concurrent.ThreadLocalRandom;
import java.util.List;
import javax.annotation.Nullable;
import java.util.Random;
import java.util.Arrays;
import javax.annotation.Nonnull;
import java.security.SecureRandom;

public class RandomUtil
{
    public static final ThreadLocal<SecureRandom> SECURE_RANDOM;
    
    public static <T> T roll(int roll, final T[] data, @Nonnull final int[] chances) {
        ++roll;
        int lower = 0;
        int upper = 0;
        for (int i = 0; i < chances.length; ++i) {
            final int thisOne = chances[i];
            upper += thisOne;
            if (roll > lower && roll <= upper) {
                return data[i];
            }
            lower += thisOne;
        }
        throw new AssertionError("Reached end of roll(" + roll + ", " + Arrays.toString(data) + ", " + Arrays.toString(chances) + ")!");
    }
    
    public static int rollInt(int roll, final int[] data, @Nonnull final int[] chances) {
        ++roll;
        int lower = 0;
        int upper = 0;
        for (int i = 0; i < chances.length; ++i) {
            final int thisOne = chances[i];
            upper += thisOne;
            if (roll > lower && roll <= upper) {
                return data[i];
            }
            lower += thisOne;
        }
        throw new AssertionError("Reached end of roll(" + roll + ", " + Arrays.toString(data) + ", " + Arrays.toString(chances) + ")!");
    }
    
    public static SecureRandom getSecureRandom() {
        return RandomUtil.SECURE_RANDOM.get();
    }
    
    public static <T> T selectRandom(@Nonnull final T[] arr, @Nonnull final Random random) {
        return arr[random.nextInt(arr.length)];
    }
    
    @Nullable
    public static <T> T selectRandomOrNull(@Nonnull final T[] arr, @Nonnull final Random random) {
        final int index = random.nextInt(arr.length + 1);
        if (index == arr.length) {
            return null;
        }
        return arr[index];
    }
    
    public static <T> T selectRandom(@Nonnull final List<? extends T> list) {
        return selectRandom(list, (Random)ThreadLocalRandom.current());
    }
    
    public static <T> T selectRandom(@Nonnull final List<? extends T> list, @Nonnull final Random random) {
        return (T)list.get(random.nextInt(list.size()));
    }
    
    static {
        SECURE_RANDOM = ThreadLocal.withInitial((Supplier<? extends SecureRandom>)SecureRandom::new);
    }
}
