package com.ruoyi.framework.aspectj;

import com.ruoyi.common.annotation.DynamicName;
import com.ruoyi.framework.handler.MonthTableNameHandler;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 切面。用户解析spel表达式，并且赋值到 {@link MonthTableNameHandler}中
 *
 * @author: pinlin
 */
@Aspect
@Component
public class DynamicNameAspect {

    /**
     * spel解析器
     */
    private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();


    /**
     * 方法形参名解析器
     */
    private static final DefaultParameterNameDiscoverer NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
    private static final Logger log = LoggerFactory.getLogger(DynamicNameAspect.class);
    @Around("execution(public * *(..))&&@annotation(com.ruoyi.common.annotation.DynamicName)")
    public Object around(ProceedingJoinPoint joinPoint ) throws Throwable {
        try {
            // 获取到spel表达式为空，默认表名则为当前日期
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            DynamicName dynamicName=method.getAnnotation(DynamicName.class);
            if (!StringUtils.hasText(dynamicName.spel())) {
                String date=  new SimpleDateFormat("yyyy_MM").format(new Date());
                MonthTableNameHandler.setData(date);
                return joinPoint.proceed();
            }
            Object[] args = joinPoint.getArgs();
            String[] paramNames = NAME_DISCOVERER.getParameterNames(method);
            Expression expression = EXPRESSION_PARSER.parseExpression(dynamicName.spel());
            EvaluationContext context = new StandardEvaluationContext();
            for (int i = 0; i < args.length; i++) {
                assert paramNames != null;
                context.setVariable(paramNames[i], args[i]);
            }
            Date tableName = expression.getValue(context, Date.class);
            log.info(tableName.toString());
            //防止注入若想查询大于当前日期之后的表默认返回当前日期
            if (StringUtils.hasText(tableName.toString())&&new Date().after(tableName)) {
                String date=  new SimpleDateFormat("yyyy_MM").format(tableName);
                //将年月存入线程
                MonthTableNameHandler.setData(date);
            }else {
                String date=  new SimpleDateFormat("yyyy_MM").format(new Date());
                //将年月存入线程
                MonthTableNameHandler.setData(date);
            }

            return joinPoint.proceed();
        } finally {
            // 释放缓存内容
            MonthTableNameHandler.removeData();
        }
    }

}
