package com.elab.core.spring;

import com.elab.core.aop.annotations.EnableElabDB;
import com.elab.core.sql.ConfigurableFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 需要代理类的注册
 *
 * @author ： liukx
 * @time ： 2020/4/1 - 19:17
 */
@Component
public class DaoScannerRegister implements ImportBeanDefinitionRegistrar, ApplicationContextAware {
    private Logger logger = LoggerFactory.getLogger(DaoScannerRegister.class);
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public ConfigurableFactory getConfigurableFactory(String configPath) {
        ConfigurableFactory configurableFactory = new ConfigurableFactory();
        configurableFactory.setSqlConfigurableLocations(configPath);
        configurableFactory.buildSqlConfigurableFactory();
        return configurableFactory;
    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        Map<String, Object> defaultAttrs = metadata
                .getAnnotationAttributes(EnableElabDB.class.getName());
        if (defaultAttrs != null) {
            Set<String> basePackageList = getBasePackages(defaultAttrs);
            if (basePackageList.size() > 0) {
                String[] basePackages = basePackageList.stream().toArray(String[]::new);
                logger.debug(" 开启ElabDB , 注解扫描指定的包 : {} ", Arrays.toString(basePackages));
                ConfigurableFactory sqlConfigurableLocations = getConfigurableFactory(defaultAttrs.get("sqlConfigurableLocations").toString
                        ());
                ClassPathDaoScanner scanner = new ClassPathDaoScanner(beanDefinitionRegistry);
                scanner.setBasicBaseDaoName("basicBaseDao");
                String proxyDataProcessName = defaultAttrs.get("proxyDataProcessName").toString();
                if (!StringUtils.isEmpty(proxyDataProcessName)) {
                    scanner.setProxyDataProcessName(proxyDataProcessName);
                }
                scanner.setResourceLoader(this.applicationContext);
                scanner.setConfigurableFactory(sqlConfigurableLocations);
                //
                scanner.registerFilters();
                //注册对应的daoInterface
                scanner.scan(basePackages);
            }
        }
    }

    protected Set<String> getBasePackages(Map<String, Object> attributes) {

        Set<String> basePackages = new HashSet<>();
        for (String pkg : (String[]) attributes.get("value")) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(pkg);
            }
        }
        for (String pkg : (String[]) attributes.get("basePackages")) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(pkg);
            }
        }
        for (Class<?> clazz : (Class[]) attributes.get("basePackageClasses")) {
            basePackages.add(ClassUtils.getPackageName(clazz));
        }

        return basePackages;
    }
}
