package de.intarsys.tools.reflect;

import java.io.File;
import java.io.FileFilter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import de.intarsys.tools.string.StringTools;

/**
 * Tool methods for handling {@link ClassLoader} instances.
 */
public class ClassLoaderTools {

	public static ClassLoader createClassLoader(ClassLoader parent,
			File baseDir, String classpath, String classpathScan,
			String classpathScanExclude) {
		URL[] urlArray = createURLs(baseDir, classpath, classpathScan,
				classpathScanExclude);
		URLClassLoader classLoader = new URLClassLoader(urlArray, parent);
		return classLoader;
	}

	public static void createURL(List<URL> urls, File file) {
		if (file.isFile()) {
			try {
				urls.add(new URL("file", "", file.getAbsolutePath())); //$NON-NLS-1$ //$NON-NLS-2$
			} catch (MalformedURLException e) {
				// couldn't possibly happen
			}
		} else {
			try {
				urls.add(new URL("file", "", file.getAbsolutePath() //$NON-NLS-1$ //$NON-NLS-2$
						+ "/")); //$NON-NLS-1$
			} catch (MalformedURLException e) {
				// couldn't possibly happen
			}
		}
	}

	public static URL[] createURLs(File baseDir, String classpath,
			String classpathScan, String classpathScanExclude) {
		List<URL> urls = new ArrayList<URL>();
		//
		if (!StringTools.isEmpty(classpath)) {
			String[] names = classpath.split(";");
			for (String name : names) {
				File file = new File(name);
				if (!file.isAbsolute()) {
					file = new File(baseDir, name);
				}
				createURL(urls, file);
			}
		}
		//
		if (!StringTools.isEmpty(classpathScan)) {
			String[] names = classpathScan.split(";");
			List<String> exclude;
			if (StringTools.isEmpty(classpathScanExclude)) {
				exclude = new ArrayList<String>();
			} else {
				exclude = Arrays.asList(classpathScanExclude.split(";"));
			}
			for (String name : names) {
				File file = new File(name);
				if (!file.isAbsolute()) {
					file = new File(baseDir, name);
				}
				createURLScanJar(urls, file, exclude);
			}
		}
		//
		URL[] urlArray = urls.toArray(new URL[urls.size()]);
		return urlArray;
	}

	public static void createURLScanJar(List<URL> result, File directory,
			final List<String> exclude) {
		File[] jarFiles = directory.listFiles(new FileFilter() {
			public boolean accept(File path) {
				return (path.isFile() && path.canRead()
						&& path.getName().toLowerCase().endsWith(".jar") && !exclude
						.contains(path.getName()));
			}
		});
		if (jarFiles != null) {
			for (File file : jarFiles) {
				try {
					result.add(new URL("file", "", file.getAbsolutePath())); //$NON-NLS-1$ //$NON-NLS-2$
				} catch (MalformedURLException e) {
					// couldn't possibly happen
				}
			}
		}
	}

}
