package com.sy.coinage.runner;

import com.sy.coinage.core.annotation.ActiveFastJsonProfile;
import com.sy.coinage.core.annotation.VoProfileRegistry;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeansException;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

/**
 * -初始执行类
 *
 * @author lug 2021年6月2日
 */
@Slf4j
@Order(1)
@Component
public class MyRunner implements ApplicationRunner, ApplicationContextAware {

    private AnnotationConfigServletWebServerApplicationContext myapplicationContext;

    private ConcurrentHashMap<String, ActiveFastJsonProfile> hashmap =
                    new ConcurrentHashMap<String, ActiveFastJsonProfile>();

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 自定义响应序列化注解初始化加载
        this.initActiveFastJsonProfileAnnotation();
        log.debug("项目初始执行={}", "加载字典到缓存");
    }

    /**
     * -自定义响应序列化注解初始化加载
     *
     * @throws Exception
     */
    public void initActiveFastJsonProfileAnnotation() throws Exception {
        RequestMappingHandlerMapping handlerMapping = myapplicationContext.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
        for (HandlerMethod handlerMethod : handlerMethods.values()) {
            Class<?> beanType = handlerMethod.getBeanType();
            ActiveFastJsonProfile activeFastJsonProfileAnnotation =
                            handlerMethod.getMethodAnnotation(ActiveFastJsonProfile.class);
            if (null == activeFastJsonProfileAnnotation) {
                continue;
            }
            // 获取方法级别的映射
            RequestMapping requestMapping = handlerMethod.getMethodAnnotation(RequestMapping.class);
            String[] methodLevelRequestMappingUrls = requestMapping.value();
            RequestMapping classLevelRequestMapping = beanType.getAnnotation(RequestMapping.class);
            String[] classLevelRequestMappingUrls;
            if (null != classLevelRequestMapping) {
                classLevelRequestMappingUrls = classLevelRequestMapping.value();
                for (String methodLevelRequestMappingUrl : methodLevelRequestMappingUrls) {
                    for (String classLevelRequestMappingUrl : classLevelRequestMappingUrls) {
                        String qualifiedUrl = classLevelRequestMappingUrl + methodLevelRequestMappingUrl;
                        hashmap.put(qualifiedUrl, activeFastJsonProfileAnnotation);
                    }
                }
            } else {
                for (String methodLevelRequestMappingUrl : methodLevelRequestMappingUrls) {
                    hashmap.put(methodLevelRequestMappingUrl, activeFastJsonProfileAnnotation);
                }
            }
        }
        myapplicationContext.registerBean(VoProfileRegistry.class);
        VoProfileRegistry registry = myapplicationContext.getBean(VoProfileRegistry.class);
        registry.setHashmap(hashmap);
    }

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

}
