package com.izouma.nineth.aspect;

import com.anji.captcha.util.StringUtils;
import com.izouma.nineth.exception.BusinessException;
import com.izouma.nineth.service.security.RequestCipherService;
import lombok.extern.slf4j.Slf4j;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 *
 * 加解密处理
 *
 */
@Aspect
@Component
@Slf4j
public class RequestCipherInterceptor {

    private static final LocalVariableTableParameterNameDiscoverer DISCOVERER = new LocalVariableTableParameterNameDiscoverer();

    private static final ExpressionParser PARSER = new SpelExpressionParser();

    @Autowired
    private RequestCipherService requestCipherService;

    @Pointcut("@annotation(com.izouma.nineth.aspect.RequestCipher)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {

        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        Method targetMethod = AopUtils.getMostSpecificMethod(methodSignature.getMethod(), point.getTarget().getClass());
        String targetName = point.getTarget().getClass().getName();
        String methodName = point.getSignature().getName();
        Object[] arguments = point.getArgs();

        boolean hasProcess = false;
        Annotation[][] annotations = targetMethod.getParameterAnnotations();
        for(int i = 0 ; i < annotations.length; i++){
            Annotation[] itemAry  =  annotations[i];
            //加密或解密参数
            for(Annotation item : itemAry){
                if(item instanceof CipherParam){
                    CipherParam cipherParam = (CipherParam) item;
                    Object res = null;
                    String cipherData = Objects.toString(arguments[i], "");
                    if(StringUtils.isEmpty(cipherData)){
                        throw new BusinessException("密文不能为空");
                    }

                    if(cipherParam.mode()){
                        res = requestCipherService.encryptData(cipherData);
                    }else{
                        res = requestCipherService.decryptData(cipherData);
                    }
                    //设置处理后的数据
                    arguments[i] = res;
                    hasProcess = true;
                }
            }

        }

        //如果没有标记处理，默认处理第一个
        if(!hasProcess && arguments.length > 0){
            //默认解密操作
            Object res = requestCipherService.decryptData(Objects.toString(arguments[0], ""));
            arguments[0] = res;
        }

        Object result = point.proceed(arguments);
        return result;
    }


}