
package com.lideeyunji.core.framework.config.btncommand.definable;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import com.lideeyunji.tool.framework.common.constant.lideeYunJiBaseConstant;
import com.lideeyunji.tool.framework.exception.lideeYunJiException;
import com.lideeyunji.core.framework.utils.Func;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AssignableTypeFilter;

import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
public class DefinablePluginManager<T> {

    //从数据库读取，放入到map
     public static Map<String,String> classNameMap=null;


    //只保留最近10个常用的
    Cache<String, DefinableButtonPlugin> cache = CacheUtil.newLRUCache(10);

    static {
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        scanner.addIncludeFilter(new AssignableTypeFilter(DefinableButtonPlugin.class));
        Set<BeanDefinition> candidates = scanner.findCandidateComponents(lideeYunJiBaseConstant.BASE_PACKAGES);

        // 创建类名映射 key=类名称 ，value=类全名
       classNameMap = candidates.stream()
                .map(candidate -> candidate.getBeanClassName())
                .collect(Collectors.toMap(
                        fullClassName -> fullClassName.substring(fullClassName.lastIndexOf(".") + 1),
                        fullClassName -> fullClassName
                ));
    }

    //初始化实例
    public static DefinableButtonPlugin initClazz(String clazzStr) {
        try {
            Class<?> clazz = Class.forName(clazzStr);
            DefinableButtonPlugin definableButtonPlugin = (DefinableButtonPlugin)clazz.newInstance();//实例化
            return definableButtonPlugin;
        } catch (Exception e) {
            throw new lideeYunJiException(e.getMessage());
        }
    }


    //添加插件
    public void addPlugin(String key, DefinableButtonPlugin plugin) {
        cache.put(key, plugin);
    }

    //移除
    public void remove(String key) {
        if (cache.containsKey(key)) {
            cache.remove(key);
        }
    }

    public DefinableButtonPlugin getPlugin(String key) {
        if (cache.containsKey(key)) {
            return cache.get(key);
        }
        if(!classNameMap.containsKey(key)){
            log.error("自定义按钮控件不存在==》"+key);
            return null;
        }

        //没有在队列里面，则重新实例化
        String clazzUrl = classNameMap.get(key);

        addPlugin(key, initClazz(clazzUrl));
        return cache.get(key);
    }

    //运行插件
    public Object executePlugin(String key,T param) {
        DefinableButtonPlugin plugin = this.getPlugin(key);
        if(Func.isEmpty(plugin)){
            return null;
        }
        return plugin.execute(param);
    }


}
