package com.elab.redis.utils;

import com.elab.redis.annotation.CacheLoopSubmit;
import com.elab.redis.model.annotation.LoopSubmitModel;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAttributes;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.Set;

/**
 * 缓存解析类
 *
 * @author ： liukx
 * @time ： 2020/7/9 - 19:42
 */
public class CacheParseUtil {

    /**
     * 是否包含特定注解集合
     *
     * @param annotations 注解列表
     * @param element     对象元素
     * @return
     */
    public static boolean isContainAnnotations(Set<Class<? extends Annotation>> annotations, AnnotatedElement element) {
        boolean isContain = false;
        for (Class<? extends Annotation> annotation : annotations) {
            if (isContainAnnotation(element, annotation)) {
                isContain = true;
                break;
            }
        }
        return isContain;
    }

    /**
     * 是否包含特定的注解
     *
     * @param element
     * @param annotation
     * @return
     */
    public static boolean isContainAnnotation(AnnotatedElement element, Class<? extends Annotation> annotation) {
        return AnnotatedElementUtils.hasAnnotation(element, annotation);
    }


    public static boolean isLoopSubmit(AnnotatedElement element) {
        AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
                element, CacheLoopSubmit.class, false, false);
        if (attributes != null) {
            return true;
        }
        return false;
    }

    public static LoopSubmitModel parseLoopSubmit(AnnotatedElement element) {
        AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
                element, CacheLoopSubmit.class, false, false);
        if (attributes != null) {
            String cacheName = attributes.getString("cacheName");
            String[] unionKeys = attributes.getStringArray("unionKey");
            LoopSubmitModel model = new LoopSubmitModel();
            model.setCacheName(cacheName);
            model.setUnionKey(unionKeys);
            return model;
        }

        return null;
    }

    /**
     * 通过key定义的集合到对应的参数里面生成对应的唯一键
     * 非键值对类型: [0]
     * 键值对类型: [0]{xxx}
     *
     * @param unionKey  唯一key集合
     * @param arguments 参数集合
     * @return
     * @throws Exception
     */
    public static String generateUnionKey(String[] unionKey, Object[] arguments) throws Exception {
        StringBuffer unionValue = new StringBuffer();
        for (int i = 0; i < unionKey.length; i++) {
            String key = unionKey[i];
            if (key.startsWith("[")) {
                String paramIndex = getParamIndex(key, "[", "]");
                Integer index = Integer.valueOf(paramIndex);
                Object value = null;

                if (key.indexOf("{") > -1) {
                    String property = getParamIndex(key, "{", "}");
                    value = BeanUtils.getProperty(arguments[index], property);
                } else {
                    value = arguments[index];
                }

                if (value == null) {
                    unionValue.append(":");
                } else {
                    unionValue.append(value + ":");
                }
            }
        }
        return unionValue.toString();
    }

    public static String getParamIndex(String str, String startSymbol, String endSymbol) {
        int start = str.indexOf(startSymbol) + 1;
        int end = str.indexOf(endSymbol, start);
        String content = str.substring(start, end);
        return content;
    }
}
