package com.fjhx.common.aspect;

import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.fjhx.common.constant.SourceConstant;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class DataSourceAspect {

    private static final Set<String> dataSourceSet = new HashSet<>();

    static {
        Class<SourceConstant> sourceConstantClass = SourceConstant.class;
        Field[] declaredFields = sourceConstantClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            dataSourceSet.add(declaredField.getName().toLowerCase());
        }
    }

    @Pointcut("execution (* com.fjhx.*.service.*.*.*(..))")
    public void pointcut() {

    }

    @Around(value = "pointcut()")
    public Object before(ProceedingJoinPoint point) throws Throwable {
        Object target = point.getTarget();
        String name = target.getClass().getName();
        String moduleName = name.split("\\.")[2];

        String peek = DynamicDataSourceContextHolder.peek();
        if (Objects.equals(peek, moduleName)) {
            return point.proceed();
        }

        if (dataSourceSet.contains(moduleName)) {
            try {
                DynamicDataSourceContextHolder.push(moduleName);
                return point.proceed();
            } finally {
                DynamicDataSourceContextHolder.poll();
            }
        } else {
            return point.proceed();
        }
    }


}
