package com.yunyan.business.document.templateEpStrategy;

import com.yunyan.business.constant.TemplateEpType;
import com.yunyan.common.exception.ServiceException;
import com.yunyan.common.utils.StringUtils;
import com.yunyan.common.utils.spring.ApplicationContextHelper;
import lombok.extern.slf4j.Slf4j;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Slf4j
public class AnnotationTplStrategyFactory {


    /**
     * 存储策略
     */
    static Map<String, TplStrategy> strategyMap = new HashMap<>();

    static {
        registerChargeStrategy();
    }

    /**
     *     通过map获取策略，当增加新的策略时无需修改代码
     */
    public static TplStrategy getTemplateStrategy(String typeKey) throws Exception {
        //默认值
        if(StringUtils.isBlank(typeKey) || "0".equals(typeKey)) {
            typeKey = TemplateEpType.Y2022FT1.getCode();
        }

        // 当增加新的类型时，需要修改代码
        if (strategyMap.containsKey(typeKey)) {
            return strategyMap.get(typeKey);
        } else {
            log.error("模板导出未配置相应策略");
            throw new ServiceException("模板导出未配置相应策略");
        }
    }


    /**
     * 自动注册策略
     *
     * // 通过反射找到所有的策略子类进行注册
     */
    private static void registerChargeStrategy() {

        // 通过反射找到所有的子类
        Reflections reflections = new Reflections(new ConfigurationBuilder()
                .setUrls(ClasspathHelper.forPackage(TplStrategy.class.getPackage().getName()))
                .setScanners(new SubTypesScanner()));
        Set<Class<? extends TplStrategy>> taxStrategyClassSet = reflections.getSubTypesOf(TplStrategy.class);

        if (taxStrategyClassSet != null) {
            for (Class<?> clazz : taxStrategyClassSet) {

                // 找到类型注解
                if (clazz.isAnnotationPresent(TemplateEpTypeAnnotation.class)) {
                    TemplateEpTypeAnnotation taxTypeAnnotation = clazz.getAnnotation(TemplateEpTypeAnnotation.class);
                    TemplateEpType templateEpType = taxTypeAnnotation.templateEpType();

                    TplStrategy tplStrategy = null;
                    /*try {
                        tplStrategy =  (TplStrategy) clazz.newInstance();
                    } catch (InstantiationException | IllegalAccessException e) {
                        log.error("获取子类异常 [{}], [{}]", e.getMessage(), e);
                        continue;
                    }*/

                    //service方式
                    tplStrategy = (TplStrategy) ApplicationContextHelper.popBean(clazz);

                    strategyMap.put(templateEpType.getCode(), tplStrategy);
                }
            }
        }
    }



    /*private static void registerChargeStrategy() {
// 找到类型注解，自动完成策略注册

// 通过反射找到所有的策略子类进行注册
        Reflections reflections = new Reflections(new ConfigurationBuilder()
                .setUrls(ClasspathHelper.forPackage(TplStrategy.class.getPackage().getName()))
                .setScanners(new SubTypesScanner()));
        Set<Class<? extends TplStrategy>> taxStrategyClassSet = reflections.getSubTypesOf(TplStrategy.class);

        if (taxStrategyClassSet != null) {
            for (Class<?> clazz : taxStrategyClassSet) {
                // 找到类型注解，自动完成策略注册
                if (clazz.isAnnotationPresent(TemplateEpTypeAnnotation.class)) {
                    TemplateEpTypeAnnotation typeAnnotation = clazz.getAnnotation(TemplateEpTypeAnnotation.class);
                    TemplateEpType chargeType = typeAnnotation.templateEpType();
                    try {
                        chargeStrategyMap.put(chargeType, (ChargeStrategy) clazz.newInstance());
                    } catch (InstantiationException | IllegalAccessException e) {
                        e.getStackTrace();
                    }
                }
            }
        }
    }*/

}
