package cd.casic.plugin.core.register;

import cd.casic.plugin.dataobject.pojo.PluginInfo;
import cd.casic.plugin.function.IPluginProcessor;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.extra.spring.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springdoc.api.AbstractOpenApiResource;
import org.springdoc.core.service.OpenAPIService;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Locale;
import java.util.Set;

/**
 * @description: TODO
 * @author: mianbin
 * @date: 2025/5/22 20:17
 * @version: 1.0
 */
@Slf4j
@Component
public class SpringDocProcessor implements IPluginProcessor {
    private Set<Class<?>> restControllers;
    private OpenAPIService openAPIService;

    @Override
    public void initialize() throws Exception {
        ApplicationContext applicationContext = SpringUtil.getApplicationContext();
        AbstractOpenApiResource openApiResource = applicationContext.getBean(AbstractOpenApiResource.class);
        try {
            // 获取OpenApiResource的ADDITIONAL_REST_CONTROLLERS字段
            Field additionalRestControllers = ReflectUtil.getField(openApiResource.getClass(), "ADDITIONAL_REST_CONTROLLERS");
            additionalRestControllers.setAccessible(true);
            restControllers = (Set<Class<?>>) additionalRestControllers.get(openApiResource);
        } catch (IllegalAccessException e) {
            restControllers = null;
        }
        openAPIService = applicationContext.getBean(OpenAPIService.class);
    }

    @Override
    public void registry(PluginInfo plugin) throws Exception {
        if (restControllers != null) {
            // 将插件中的Controller类添加到OpenApiResource的ADDITIONAL_REST_CONTROLLERS字段
            restControllers.addAll(plugin.getControllers());
            refresh();
        }
    }

    @Override
    public void unRegistry(PluginInfo plugin) throws Exception {
        if (restControllers != null && !restControllers.isEmpty()) {
            for (Class<?> clazz : plugin.getControllers()) {
                // 从OpenApiResource的ADDITIONAL_REST_CONTROLLERS字段中移除插件中的Controller类
                restControllers.remove(clazz);
            }
            refresh();
            plugin.getControllers().clear();
        }
    }

    private void refresh() {
        if (openAPIService != null) {
            // 手动刷新OpenApiResource
            openAPIService.setCachedOpenAPI(null, Locale.getDefault());
            // openAPIService.resetCalculatedOpenAPI();
        }
    }
}
