/*
 * Créé le 8 nov. 2006
 * 
 */
package fr.gouv.finances.cp.xemelios.importers.batch;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.Properties;

import fr.gouv.finances.cp.utils.PropertiesExpansion;

/**
 * This class load config file and launch the real batch importer.
 * 
 * 
 * @since 3.1
 * 
 * @author jptessier,chm
*/
public class BatchImporter{
	
	//private static Logger logger = Logger.getLogger(BatchImporter.class);
	private static final Class[] parameters = new Class[] { URL.class };

	
	static void restoreProperties() {
		
		Properties properties = new PropertiesExpansion();
		String propsFileName = System.getProperty("xemelios.properties");
		if (propsFileName == null) {
			propsFileName = "xemelios.properties";
		} // fichier de ce nom dans rep courant
		File propsFile = new File(propsFileName);
		try {
			if (propsFile.isFile() && propsFile.canRead()) {
			} else {
				System.err.println("Impossible d'accéder à " + propsFileName);
			}
		}
		catch (SecurityException se) {
			System.err.println("Problème d'accès au fichier " + propsFileName);
		}
		if (propsFile != null) {
			try {
				FileInputStream in = new FileInputStream(propsFile);
				properties.load(in);
			}
			catch (IOException ioe) {
				System.err.println("Cannot load properties " + ioe);
				return;
			}
		}
		for (Enumeration en = properties.keys(); en.hasMoreElements();) {
			String k = (String)en.nextElement();
			Object v = properties.get(k);
			if (v instanceof String) {
				System.setProperty(k, (String)v);
			}
		}
	}
	public static void addURL(URL u) throws IOException {
		
		URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
		Class sysclass = URLClassLoader.class;
		
		try {
			Method method = sysclass.getDeclaredMethod("addURL", parameters);
			method.setAccessible(true); // voyou
			method.invoke(sysloader, new Object[] { u });
		}
		catch (Throwable t) {
			t.printStackTrace();
			throw new IOException("Error, could not add URL to system classloader");
		}// end try catch
		
	}// end method
	
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		
		restoreProperties();
		String classdirs = System.getProperty("classdirs");
		String startclass = "fr.gouv.finances.cp.xemelios.importers.batch.BatchRealImporter";
		String[] classdirsArray = classdirs.split(";");
		
		for (int dir = 0; dir < classdirsArray.length; ++dir) {
			try {
				File jarsdir = new File(classdirsArray[dir]);
				addURL(new URL("file:" + jarsdir.getAbsolutePath()));// Le
				// directory
				// itself
				File[] listJars = jarsdir.listFiles(new FileFilter() {
					public boolean accept(File pathname) {
						String s = pathname.getPath();
						return s.endsWith(".jar");
					}
				});
				for (int i = 0; i < listJars.length; ++i) // Chacun des jars
				{
					
					addURL(new URL("file:" + listJars[i].getAbsolutePath()));
				}
			}
			catch (NullPointerException n) {
				System.err.println("Impossible de trouver le repertoire " + classdirsArray[dir]);
			}
		}
		
//		org.apache.log4j.xml.DOMConfigurator.configure(System.getProperty("xemelios.log4j.xml"));
		
		String SnewInstance = System.getProperty("startclass.newInstance");
		boolean newInstance = (new Boolean(SnewInstance)).booleanValue();
		String SinstanceMethod = System.getProperty("startclass.instanceMethod");
		String SclassMethod = System.getProperty("startclass.classMethod");
		String SclassMethodArgs = null;
		if("main".equals(SclassMethod)) {
			if(args!=null && args.length>0) {
				StringBuffer sb = new StringBuffer();
				for(String arg:args) sb.append(arg).append(",");
				SclassMethodArgs = sb.toString();
			} else SclassMethodArgs = "/xxx";	// voila un nom de fichier xui a peu de chance dexister dans le repertoire racine
		} else {
			SclassMethodArgs= System.getProperty("startclass.classMethod.Args");
		}
		Class startClass = Class.forName(startclass);
		if (SclassMethod != null) {
			if (SclassMethodArgs != null) {
				// Que des Strings
				//System.out.println(SclassMethodArgs);
				String[] classMethodArgsArray = SclassMethodArgs.split(",");
//System.out.print("classMethodArgsArray=");
//for(String s:classMethodArgsArray) { System.out.print(s); System.out.print(";"); }
//System.out.println();
				Class[] params = new Class[] { String[].class };
				Method classMethod = startClass.getDeclaredMethod(SclassMethod, params);
				//System.out.println(classMethod.toGenericString());
				Object[] parametersValues = new Object[] {classMethodArgsArray};
//System.out.println("parametersValues="+parametersValues);
				classMethod.invoke(null, parametersValues);
				
			} else {
				// methode sans parametre
				Method classMethod = startClass.getDeclaredMethod(SclassMethod);
				classMethod.invoke(null);
			}
		}
		if (SinstanceMethod != null) {
			newInstance = true;
		}
		if (newInstance) {
			Object instance = startClass.newInstance();
			if (SinstanceMethod != null) {
				// idem methode sans parametre
				Method instanceMethod = startClass.getDeclaredMethod(SinstanceMethod);
				instanceMethod.invoke(instance);
			}
		}
	}
}
