package com.cf.imes.module.report.framework.ureport.config;

import com.cf.imes.module.report.framework.ureport.annotation.CfReportSpringbeanDatasource;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.StringUtils;

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

/**
 * 扫描com.cf.imes.module.report.framework.ureport.bean下的类，带有CfReportSpringbeanDatasource的类注入到spring中
 *
 * @author Gqr
 * @since 2024/7/11 17:21
 */
public class CfReportSpringbeanRegistrar implements ImportBeanDefinitionRegistrar {

    private static final TypeFilter cfReportSpringBeanDatasourceFilter = (metadataReader, metadataReaderFactory) -> metadataReader.getAnnotationMetadata().hasAnnotation(CfReportSpringbeanDatasource.class.getName());

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry);
        scanner.addIncludeFilter(cfReportSpringBeanDatasourceFilter); // 添加自定义的过滤器
        Set<BeanDefinition> candidates = scanner.findCandidateComponents("com.cf.imes.module.report.framework.ureport.bean");

        for (BeanDefinition candidate : candidates) {
            AnnotatedBeanDefinition beanDef = (AnnotatedBeanDefinition) candidate;
            Map<String, Object> attributes = beanDef.getMetadata().getAnnotationAttributes(CfReportSpringbeanDatasource.class.getName());
            if (attributes != null) {
                // 校验注解上的value
                String value = (String) attributes.get("value");
                if (!StringUtils.hasText(value)) {
                    throw new IllegalArgumentException("@CfReportSpringbean requires a non-empty 'value' attribute.");
                }
                // 校验注解上的name
                String name = (String) attributes.get("name");
                if (!StringUtils.hasText(name)) {
                    throw new IllegalArgumentException("@CfReportSpringbean requires a non-empty 'name' attribute.");
                }
                String beanClassName = candidate.getBeanClassName();
                if (StringUtils.hasText(beanClassName)) {
                    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanClassName);
                    registry.registerBeanDefinition(value, builder.getBeanDefinition());
                }
            }
        }
    }
}
