package com.njcn.csdevice.controller.bean;


import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.csdevice.controller.annotation.InsertBean;
import com.njcn.csdevice.controller.annotation.QueryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Field;

/**
 * @author hongawen
 * @version 1.0
 * @data 2024/11/7 11:31
 */
@Component
public class DynamicBeanProcessor implements BeanPostProcessor {

    @Autowired
    private ApplicationContext context;

    /**
     * 查询配置
     */
    @Value("${data.source.query:Influxdb}")
    private String queryParam;

    /**
     * 插入配置
     */
    @Value("${data.source.insert:Relation}")
    private String insertParam;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean.getClass().isAnnotationPresent(Controller.class) || bean.getClass().isAnnotationPresent(RestController.class) || bean.getClass().isAnnotationPresent(Service.class)) {
            processFields(bean);
        }
        return bean;
    }

    private void processFields(Object bean) {
        Field[] fields = bean.getClass().getDeclaredFields();
        for (Field field : fields) {
            String beanId;
            Class<?> type = field.getType();
            // 判断是否是接口类型，并且是否是注解指定类库
            if (type.isInterface() && (field.isAnnotationPresent(QueryBean.class) || field.isAnnotationPresent(InsertBean.class))) {
                String name = type.getName();
                beanId = name.substring(name.lastIndexOf(".") + 2);
                if (field.isAnnotationPresent(QueryBean.class)) {
                    beanId = queryParam + beanId + "Impl";
                } else if (field.isAnnotationPresent(InsertBean.class)) {
                    beanId = insertParam + beanId + "Impl";
                }
                try {
                    field.setAccessible(true);
                    field.set(bean, context.getBean(beanId));
                } catch (IllegalAccessException e) {
                    throw new BusinessException("获取动态实现类失败");
                }
            }
        }
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}
