package de.dhbwstuttgart.parser;

import de.dhbwstuttgart.typecheck.JavaClassName;
import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;

import java.util.LinkedList;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.lang.InterruptedException;
/**
 * Hilft beim Durchsuchen von Packages
 * Benutzt die Reflections-Library (https://github.com/ronmamo/reflections)
 * Hilfe dazu: http://stackoverflow.com/a/9571146
 */
public class PackageCrawler {

    public static Set<Class<?>> getClassesInPackage(String packageName){
        List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>();
        classLoadersList.add(Thread.currentThread().getContextClassLoader());
        classLoadersList.add(ClasspathHelper.staticClassLoader());
        classLoadersList.add(Thread.currentThread().getContextClassLoader().getParent());

        Reflections reflections = new Reflections(new ConfigurationBuilder()
                .setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
                .setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0])))
                .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix(packageName))));

        Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);

        return classes;
    }
    
  // Returns a list of JavaClassNames.
  public static List<JavaClassName> getClassNames(String packageName){
    List<JavaClassName> nameList = new ArrayList();
    Set<Class<?>> classes = getClassesInPackage(packageName);
    for(Class c : classes){
      nameList.add(new JavaClassName(c.getName()));
    }
    return nameList;
  }
}
