package com.config;

import com.controller.ReaderController;
import com.controller.api.InventoryController;
import com.controller.log.LogController;
import com.controller.school.SchoolIndexController;
import com.jfinal.config.Constants;
import com.jfinal.config.*;
import com.jfinal.core.JFinal;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.cron4j.Cron4jPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.template.Engine;
import com.model._MappingKit;

import com.utils.ClassUtils;

import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * 本 demo 仅表达最为粗浅的 jfinal 用法，更为有价值的实用的企业级用法
 * 详见 JFinal 俱乐部: http://jfinal.com/club
 *
 * API引导式配置
 */
public class MyJfinalConfig extends JFinalConfig {

	/**
	 * 运行此 main 方法可以启动项目，此main方法可以放置在任意的Class类定义中，不一定要放于此
	 *
	 * 使用本方法启动过第一次以后，会在开发工具的 debug、run config 中自动生成
	 * 一条启动配置，可对该自动生成的配置再添加额外的配置项，例如 VM argument 可配置为：
	 * -XX:PermSize=64M -XX:MaxPermSize=256M
	 */
	public static void main(String[] args) {
		 JFinal.start("src/main/webapp", 80, "/");
	}

	/**
	 * 定时器插件
	 * 在此处添加定时任务
	 * 时间设置规则 参照jfinal官方文档
	 * @param me
	 */
	private void loderCron4jPlugin(Plugins me){
		Cron4jPlugin task = new Cron4jPlugin();
		me.add(task);
		me.add(new EhCachePlugin(getClass().getClassLoader().getResource("resources/ehcache.xml")));
	}
	/**
	 * 配置常量
	 */
	public void configConstant(Constants me) {
		PropKit.use("config.txt");
		me.setDevMode(PropKit.getBoolean("devMode", true));
		me.setMaxPostSize(50240000);
	}

	/**
	 * 配置路由
	 */
	public void configRoute(Routes me) {
		try{
			registAction(me,com.controller.ReaderController.class.getPackage());
			registAction(me,com.controller.sysconfig.SysConfigController.class.getPackage());
			registAction(me,com.controller.report.CirculationStatisticsController.class.getPackage());
			registAction(me,com.controller.screendisplay.ScreenHomeController.class.getPackage());
			registAction(me,SchoolIndexController.class.getPackage());
			registAction(me, InventoryController.class.getPackage());
			registAction(me, LogController.class.getPackage());
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	private void registAction(Routes me,Package pack) throws Exception{
		Set<Class<?>> classSet = getClasses(pack);
		Iterator ite = classSet.iterator();
		while(ite.hasNext()){
			Class cls = (Class) ite.next();
			if(cls.isAnnotationPresent(ControllerInterface.class)){
				ControllerInterface first = (ControllerInterface)cls.getAnnotation(ControllerInterface.class);
				me.add(first.path(),cls);
			}
		}
	}

	public void configEngine(Engine me) {
		me.addSharedFunction("/common/_layout.html"); //教育局-后台模板
		//me.addSharedFunction("/teachBefore/_beforeLayout.html"); //教育局-前台模板
		me.addSharedFunction("/common/_paginate.html");
	}

	/**
	 * 配置插件
	 */
	public void configPlugin(Plugins me) {
		// 配置 druid 数据库连接池插件
		DruidPlugin druidPlugin = new DruidPlugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password").trim());
		me.add(druidPlugin);

		// 配置ActiveRecord插件
		ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);

		//配置日志输出
		//SqlReporter.setLog(true);
		//arp.setShowSql(true);
		arp.setDialect(new MysqlDialect());

		// 所有映射在 MappingKit 中自动化搞定
		_MappingKit.mapping(arp);
		me.add(arp);
		loderCron4jPlugin(me);
	}

	public static DruidPlugin createDruidPlugin() {
		return new DruidPlugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password").trim());
	}

	/**
	 * 配置全局拦截器
	 */
	public void configInterceptor(Interceptors me) {

		me.add(new AuthInterceptor());
		me.add(new LogInterceptor());
//		me.add(new XssInterceptor());
	}

	/**
	 * 配置处理器
	 */
	public void configHandler(Handlers me) {
	//	me.add(new AuthHandler());
		me.add(new XssHandler("[%--`~!@#$^&*()=|{}':;',\\\\[\\\\].<>/?~！@#￥……&*（）――|{}【】‘；：”“'。，、？]"));
		me.add(new WebSocketHandler("^/websocket"));
	}

	private Set<Class<?>> getClasses(Package pack) throws Exception{
		if(JFinal.me().getConstants().getDevMode() == true){//如果是开发模式，读取WEB-INFO/classes目录下的文件
			return ClassUtils.getClasses(pack);
		}
		//如果不是开发模式，读取mes.jar包中的class
		Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
		String packageName = pack.getName();
		String packageDirName = packageName.replace('.', '/');
		java.net.URL url = ReaderController.class.getProtectionDomain().getCodeSource()
				.getLocation();
		String filePath = java.net.URLDecoder.decode(url.getPath(), "utf-8");

		Enumeration enu = new JarFile(filePath).entries();
		while(enu.hasMoreElements()){
			JarEntry element = (JarEntry) enu.nextElement();
			String name = element.getName();
			if(name.indexOf(packageDirName)>-1 &&name.toUpperCase().endsWith(".CLASS")){
				String className = name.substring(packageName.length() + 1, name.length() - 6);
				classes.add(Class.forName(pack.getName()+"."+className));
			}
		}
		return classes;
	}

	public void afterJFinalStart() {
	}
}
