package br.ufrgs.inf.prosoft.tigris.utils;

import br.ufrgs.inf.prosoft.tigris.exceptions.ConfigurationException;
import br.ufrgs.inf.prosoft.tigris.monitoring.aspects.CustomMonitoring;
import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;

import java.util.Set;

public final class ConfigurationUtils {

    private static Reflections reflections = new Reflections(
            new ConfigurationBuilder()
                    .setUrls(ClasspathHelper.forClassLoader())
                    .setScanners(new SubTypesScanner(false), new ResourcesScanner(), new TypeAnnotationsScanner()));

    public static Class<?> getAvailableConfigurationClass(Class annotation) {
        Set<Class<?>> configurations =
                reflections.getTypesAnnotatedWith(annotation);
        if (configurations.isEmpty())
            throw new ConfigurationException(annotation.getName() + " not found.");
        if (configurations.size() > 1)
            throw new ConfigurationException(annotation.getName() + " has too many definitions.");
        return configurations.iterator().next();
    }

    public static Class<?> getAvailableCustomMonitoringClass() {
        Set<Class<? extends CustomMonitoring>> configurations =
                reflections.getSubTypesOf(CustomMonitoring.class);
        if (configurations.size() > 1)
            throw new ConfigurationException("Multiple implementations of CustomMonitoring.class.");
        if (configurations.size() == 0)
            return null;
        return configurations.iterator().next();
    }

}
