package com.ftinc.si.assist.run;

import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;

import com.ftinc.si.assist.test.Tool;
import com.ftinc.si.assist.test.gui.EnvironmentData;


public class TestMainGate {
	public static ClassLoader s_classloader = null;

	public static void main(String[] args) {
		String root_path = TestMainGate.class.getProtectionDomain().getCodeSource().getLocation().getPath();
	    File xfile = new File(root_path);

	    ArrayList<URL> pathList = new ArrayList<URL>();
	    String paths = System.getProperty("java.class.path");
	    if (paths != null && paths.length() > 0) {
	    	//Systemのクラスパスを読み取る。

	    	String[] xplist = paths.split(File.pathSeparator);
	    	for (int i = 0; i < xplist.length; i++) {
	    		xfile = new File(reformPath(xplist[i]));
	    		try {
					pathList.add(xfile.toURI().toURL());
				} catch (MalformedURLException e) {
					Tool.alertMSG(null, "@java.class.parh:" + e.getMessage());
				}
	    	}
	    }
		//DB接続を除く環境情報に設定されているパスを読込む。
	    Tool.init(false);
		EnvironmentData t_env = Tool.readEnvironment(false);
		if (t_env.rootDirs != null) {
			for (int i = 0; i < t_env.rootDirs.size(); i++) {
				xfile = new File(reformPath(t_env.rootDirs.get(i)));
				try {
					if (!pathList.contains(xfile.toURI().toURL())) {
						pathList.add(xfile.toURI().toURL());
					}
				} catch (MalformedURLException e) {
					Tool.alertMSG(null, "@rootDir:" + e.getMessage());
				}
			}
		}
		if (t_env.fakedir != null) {
			xfile = new File(reformPath(t_env.fakedir));
			try {
				if (!pathList.contains(xfile.toURI().toURL())) {
					pathList.add(xfile.toURI().toURL());
				}
			} catch (MalformedURLException e) {
				Tool.alertMSG(null, "@fakeDir:" + e.getMessage());
			}
		}

		//jarからの実行の場合、s_jarnameに版数情報がつく。その場合には、jarのパスを読み込む。
		if (Tool.s_jarname.startsWith("ftesting_")) {
			//jarからの実行である。Eclipseからではない。
//			Tool.alertMSG(null, "including ftesting_*.jar");

			xfile = new File(Tool.s_userdir + "\\" + Tool.s_jarname + ".jar");
			try {
				if (!pathList.contains(xfile.toURI().toURL())) {
					pathList.add(xfile.toURI().toURL());
				}
			} catch (MalformedURLException e) {
				Tool.alertMSG(null, Tool.s_userdir + "\\" + Tool.s_jarname + ".jar@jarDir:" + e.getMessage());
			}
			xfile = new File(Tool.s_userdir + "\\" + Tool.s_jarname + "_lib\\");
			if (xfile.exists()) {
//				Tool.alertMSG(null, "including ftesting_*_lib");
				try {
					if (!pathList.contains(xfile.toURI().toURL())) {
						pathList.add(xfile.toURI().toURL());
					}
				} catch (MalformedURLException e) {
					Tool.alertMSG(null, Tool.s_userdir + "\\" + Tool.s_jarname + "_lib@jarDir:" + e.getMessage());
				}
			}
		}

		if (pathList.size() == 0) {
			s_classloader = TestMainGate.class.getClassLoader();
		} else {
			//第二引数は、moduke-infoなどを受け継ぐために必須。
			s_classloader = new URLClassLoader(pathList.toArray(new URL[pathList.size()]), TestMainGate.class.getClassLoader());
		}

		String t_msg = "  \n";
	    Class<?> xmain;
		try {
			xmain = s_classloader.loadClass("com.ftinc.si.assist.run.TestSubMain");

//			Method[] xmlist = s_classloader.loadClass("com.ftinc.si.assist.run.CodeFairy").getDeclaredMethods();
			//上は成功する。xmainのメソッド取得のみ失敗。


			Method[] xmlist = xmain.getDeclaredMethods();
			for (int i = 0; i < xmlist.length; i++) {
				t_msg += xmlist[i].getName() + "\n";
			}

//			Tool.alertMSG(null, "getting the main Method." + t_msg);

		    Method xMethod = xmain.getDeclaredMethod("main", String[].class);

//			Tool.alertMSG(null, "invoking the main Method of SubMain.");
			xMethod.invoke(null, (Object)args);
		} catch (Exception|Error e) {
			t_msg += "cause= " + e.getCause().getMessage();
			t_msg += "\nname= " + e.getCause().getClass().getName();
			t_msg += "\nlocal= " + e.getCause().getLocalizedMessage();
			Tool.alertMSG(null, e.getClass().getName() + ">>" + e.getMessage() + t_msg);
		}
	}

	//引数のpathがjarでなければ、ディレクトリとみなし、必要に応じて"\"を付ける。
	//引数はnullではない。
	private static String reformPath(String s) {
		if (!s.toLowerCase().endsWith(".jar") && !s.endsWith("\\")) {
			return s + "\\";
		}
		return s;
	}

}
