package com.brilliance.mda.runtime.mda.listener;

import com.brilliance.mda.runtime.mda.IDaoSession;
import com.brilliance.mda.runtime.mda.IRuleEmitter;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class StartListener  implements ApplicationListener<ContextRefreshedEvent>{

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		ApplicationContext context = event.getApplicationContext();
		//EnvConfig config = context.getBean(EnvConfig.class);
		//引入全局pplication context
		//String packagePath = config.getTransPackage().replaceAll("\\.", "/");
		//扫描所有的交易
		//scanModule(context,packagePath);
		//扫描提供给MdaContext调用的Dao
		scanDao(context);
		//扫描事件触发器
		//scanEmitter(context);
	}
	
	
//	public void scanModule(ApplicationContext context,String packagePath){
//		MdaScanner scanner = context.getBean(MdaScanner.class);
//		try {
//			Set<Class<?>> clsSet = scanner.doScan(packagePath,Transaction.class);
//			//MdaDynamicGenerator.createRuleEmitter(clsSet);
//			MdaDriver.createVoSetterAndGetter(clsSet);
//			//MdaDynamicGenerator.createVoSetterAndGetter(clsSet);
//		} catch (ClassNotFoundException | IOException e) {
//			e.printStackTrace();
//		}
//	}
	
	public void scanDao(ApplicationContext context){
		Map<String,Object> beans = context.getBeansWithAnnotation(Mapper.class);
		IDaoSession daoProxy = context.getBean(IDaoSession.class);
		
		DaoCyc:
		for(Map.Entry<String, Object> entry : beans.entrySet())
		{
			Object dao = entry.getValue();
			Class<?>[] interfaces =  dao.getClass().getInterfaces();
			
			if(interfaces == null)
				continue;
			for(Class<?> inf : interfaces)
			{
				Type[] types = inf.getGenericInterfaces();
				if(types == null)
					continue;
				for(Type type:types)
				{
					if(!(type instanceof ParameterizedType))
						continue;
					Type[] paramTypes = ((ParameterizedType)type).getActualTypeArguments();
					if(paramTypes != null)
					{
						String clazzName = paramTypes[0].getTypeName();
						try{
							Class<?> clazz = Class.forName(clazzName);
							//System.out.print(paramTypes[0].getTypeName()+"->"+inf);
							daoProxy.putDao(clazz, dao);
						}catch(Exception e)
						{}
						continue DaoCyc;
					}
				}

			}
		}
	}
	public void scanEmitter(ApplicationContext context)
	{
		Map<String, IRuleEmitter> emitterMap = context.getBeansOfType(IRuleEmitter.class);
		Set<Class<?>> clsSet = new HashSet<>();
		for(Map.Entry<String, IRuleEmitter> entry:emitterMap.entrySet())
		{
			//EmitterFactory.getDefault().putRuleEmmiter(entry.getValue());
			Class<?> transactionClass = entry.getValue().relatedTransaction();
			clsSet.add(transactionClass);
		}
		MdaDriver.createVoSetterAndGetter(clsSet);
	}
}
