package com.elab.spring.utils;

import com.elab.spring.utils.event.SourceModel;
import com.xiaoleilu.hutool.lang.ClassScaner;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PatternMatchUtils;
import org.springframework.util.ResourceUtils;

import javax.xml.bind.SchemaOutputResolver;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class SpringCase {

    @Test
    public void resourceCase() throws FileNotFoundException {
        File clsFile = ResourceUtils.getFile("classpath:application.yml");
        System.out.println(clsFile);
    }

    @Test
    public void propertiesCase() throws Exception {
        Properties res = PropertiesLoaderUtils.loadProperties(new ClassPathResource("/META-INF/app.properties"));
        System.out.println(" loadProperties :" + res);

        ClassPathResource classPathResource = new ClassPathResource("/META-INF/app.properties");

        Properties ret = new Properties();
        PropertiesLoaderUtils.fillProperties(ret, classPathResource);
        System.out.println(" fillProperties :" + ret);
    }

    @Test
    public void resourcePattern() throws IOException {
        //
        PathMatchingResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resourcePatternResolver.getResources("classpath:*.yml");
        System.out.println(resources);
        Set<Class<?>> classes = ClassScaner.scanPackage("com.elab.spring.utils.event");

        Resource[] resources1 =
            ResourcePatternUtils.getResourcePatternResolver(new DefaultResourceLoader()).getResources("mapper/*");
        System.out.println(resources1);
    }

    @Test
    public void classScanCase() {
        // true：默认TypeFilter生效，这种模式会查询出许多不符合你要求的class名
        // false：关闭默认TypeFilter
        ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);

        // 扫描带有自定义注解的类
        provider.addIncludeFilter(new AnnotationTypeFilter(SpringBootTest.class));

        // 接口不会被扫描，其子类会被扫描出来
        provider.addIncludeFilter(new AssignableTypeFilter(SourceModel.class));

        // Spring会将 .换成/  ("."-based package path to a "/"-based)
        // Spring拼接的扫描地址：classpath*:xxx/xxx/xxx/**/*.class
        // Set<BeanDefinition> scanList = provider.findCandidateComponents("com.p7.demo.scanclass");
        Set<BeanDefinition> scanList = provider.findCandidateComponents("com.elab.spring.*");

        for (BeanDefinition beanDefinition : scanList) {
            System.out.println(beanDefinition.getBeanClassName());
        }

    }

    @Test
    public void patternMatchUtils() {
        System.out.println(PatternMatchUtils.simpleMatch("liu*", "liukaix"));
        System.out.println(PatternMatchUtils.simpleMatch("liu*", "li"));
        System.out.println(PatternMatchUtils.simpleMatch("liu*kai*", "liukaix"));
        System.out.println(PatternMatchUtils.simpleMatch("liu*x", "liukaix"));

        // 路径匹配
        match("/api/*/liukx", "/api/xxx/liukx");
        match("/api/lk?", "/api/lkx");
        match("/api/lk?", "/api/lkxx");
        match("/api/xxx/*.html", "/api/xxx/a.html");
        match("/api/*/aaa", "/api/lkx/aba");

        AntPathMatcher antPathMatcher = new AntPathMatcher();

        Map<String, String> stringStringMap =
            antPathMatcher.extractUriTemplateVariables("/api/{a}/{b}/{c}", "/api/1/2/3");
        System.out.println(stringStringMap);

        // 获取通配符匹配的值
        System.out.println(antPathMatcher.extractPathWithinPattern("/api/*/*.html", "/api/a.html"));

    }

    private AntPathMatcher match(String sourceUrl, String path) {
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        System.out.println(sourceUrl + " : " + path + "  > " + antPathMatcher.match(sourceUrl, path));
        return antPathMatcher;
    }

}
