
package com.lideeyunji.tool.framework.yunji.component.cache;


import com.lideeyunji.tool.framework.yunji.annotation.lideeYunjiCache;
import com.lideeyunji.tool.framework.yunji.component.properties.lideeYunjiProperties;
import com.lideeyunji.tool.framework.yunji.component.redis.lideeYunjiRedisUtils;
import com.lideeyunji.tool.framework.yunji.constant.lideeRedisConstants;
import com.lideeyunji.tool.framework.yunji.model.global.BaseWebResult;
import com.lideeyunji.tool.framework.yunji.utils.FuncBase;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * LideeYunJi低代码
 * 缓存相关
 */
@Aspect
public class lideeYunjiCacheAspect {

    private ExpressionParser parser = new SpelExpressionParser();

    private final lideeYunjiRedisUtils lideeYunjiRedisUtils;


    public lideeYunjiCacheAspect(lideeYunjiRedisUtils lideeYunjiRedisUtils) {
        this.lideeYunjiRedisUtils = lideeYunjiRedisUtils;
    }

    @Around("@annotation(lideeYunjiCache)")
    public Object aroundMethod(ProceedingJoinPoint joinPoint, lideeYunjiCache lideeYunjiCache) throws Throwable {

        if (lideeYunjiProperties.getDebug()) {//开发环境，直接跳过
            return joinPoint.proceed();
        }

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        boolean nullIsSave = lideeYunjiCache.nullIsSave();

        StandardEvaluationContext context = new StandardEvaluationContext();
        // 获取缓存key
        Object[] args = joinPoint.getArgs();

        String[] parameterNames = signature.getParameterNames();

        for (int i = 0; i < parameterNames.length; i++) {
            context.setVariable(parameterNames[i], args[i]);
        }

        String redisKey = "";
        if(lideeYunjiCache.cacheNames().contains("#")){//含有占位符
            redisKey = lideeRedisConstants.lideeyunji_PREFIX + "cache:" + parser.parseExpression(lideeYunjiCache.cacheNames()).getValue(context, String.class);
        }

        boolean delCache = lideeYunjiCache.delCache();
        if (delCache) {
            Set<String> keys = lideeYunjiRedisUtils.keys(redisKey);
            if(FuncBase.isNotEmpty(keys)){
                lideeYunjiRedisUtils.delList(keys);//删除缓存
            }
            return joinPoint.proceed();
        }


        if (lideeYunjiRedisUtils.hasKey(redisKey)) {

            Object cachedResultObj = lideeYunjiRedisUtils.get(redisKey);
            Class reflexClass = lideeYunjiCache.reflexClass();
            try {
                String cachedResultStr = String.valueOf(cachedResultObj);
                if(cachedResultStr==null){
                    return null;
                }else if(FuncBase.equals(cachedResultStr,"")){
                    return "";
                }else if(FuncBase.equals(cachedResultStr,"[]")){
                    return new ArrayList<>();
                }

                if (FuncBase.jsonIsArray(cachedResultStr)) {//当前是jsonarray，则需要转换
                    List list = FuncBase.json2List(cachedResultStr, reflexClass);
                    return list;
                } else if (FuncBase.jsonIsObject(cachedResultStr)) {//当前是json，则需要转换
                    Object obj = FuncBase.json2Bean(cachedResultStr, reflexClass);
                    return obj;
                } else {//基本数据类型
                    Class<?> longClass = Long.class;
                    if (longClass.isAssignableFrom(reflexClass)) {//因为redis存把long存进去识别为int
                        return FuncBase.toLong(FuncBase.toStr(cachedResultObj));
                    } else {
                        return cachedResultObj;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }


        }

        // 如果缓存中没有数据，则继续执行目标方法
        Object result = joinPoint.proceed();
        if (!nullIsSave && FuncBase.isEmpty(result)) {//只存有值部分
            return result;
        }

        if (FuncBase.isNotEmpty(result) && (result instanceof BaseWebResult)) {//这个类型，需要成功才做缓存
            BaseWebResult baseWebResult = (BaseWebResult) result;
            if (baseWebResult.isSuccess()) {
                // 将结果缓存
                lideeYunjiRedisUtils.set(redisKey, FuncBase.json2Str(result), lideeYunjiCache.expire(), lideeYunjiCache.timeUnit());
            }
        } else if (FuncBase.isNotEmpty(result) && (result instanceof Throwable)) {//异常类不做

        } else {
            String resultStr = FuncBase.json2Str(result);
            if (FuncBase.jsonIsJson(resultStr)) {//当前是json，则需要转换
                lideeYunjiRedisUtils.set(redisKey, resultStr, lideeYunjiCache.expire(), lideeYunjiCache.timeUnit());
            } else {//不是json，则是基本数据类型，转为字符串存储
                lideeYunjiRedisUtils.set(redisKey, result, lideeYunjiCache.expire(), lideeYunjiCache.timeUnit());
            }
        }

        return result;
    }



}