package com.sonic.frog.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 统一的缓存工具类
 * @Author zzhan
 * @Date 2021/3/4 11:27
 * @Version 1.0
 */
@Component
public class CacheUtils {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 清理String类型的缓存数据
     * @param redisKey
     */
    public void clearStringCache(String redisKey) {
        stringRedisTemplate.delete(redisKey);
    }

    /**
     * 获取指定类型的缓存对象数据
     * @param redisKey
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> T getCacheObject(String redisKey, Class<T> clazz) {
        String cacheStr = stringRedisTemplate.opsForValue().get(redisKey);
        if(StringUtils.isEmpty(cacheStr)) {
            return null;
        }
        return JSONObject.parseObject(cacheStr, clazz);
    }

    /**
     * 获取指定类型的缓存列表对象数据
     * @param redisKey
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> List<T> getCacheList(String redisKey, Class<T> clazz) {
        String cacheStr = stringRedisTemplate.opsForValue().get(redisKey);
        if(StringUtils.isEmpty(cacheStr)) {
            return null;
        }
        return JSONObject.parseArray(cacheStr, clazz);
    }

    /**
     * 获取缓存对象数据，如果缓存数据不存在的话则设置缓存对象
     * @param redisKey
     * @param clazz
     * @param abstractCache
     * @param timeSeconds
     * @param <T>
     * @return
     */
    public <T> T getCacheObjectAndSet(String redisKey, Class<T> clazz, AbstractCache abstractCache, int timeSeconds) {
        String cacheStr = stringRedisTemplate.opsForValue().get(redisKey);
        if(StringUtils.isNotEmpty(cacheStr)) {
            return JSONObject.parseObject(cacheStr, clazz);
        }
        String param = abstractCache.getData();
        if(param == null) {
            return null;
        }
        setCache(redisKey, param, timeSeconds);
        return JSONObject.parseObject(param, clazz);
    }

    /**
     * 获取缓存对象数据，如果缓存数据不存在的话则设置缓存对象
     * @param redisKey
     * @param abstractCache
     * @param timeSeconds
     * @return
     */
    public String getCacheStringAndSet(String redisKey, AbstractCache abstractCache, int timeSeconds) {
        String cacheStr = stringRedisTemplate.opsForValue().get(redisKey);
        if(StringUtils.isNotEmpty(cacheStr)) {
            return cacheStr;
        }
        String param = abstractCache.getData();
        if(param == null) {
            return null;
        }
        setCache(redisKey, param, timeSeconds);
        return param;
    }

    /**
     * 获取缓存列表数据，如果缓存数据不存在的话则设置缓存列表
     * @param redisKey
     * @param clazz
     * @param abstractCache
     * @param timeSeconds
     * @param <T>
     * @return
     */
    public <T> List<T> getCacheListAndSet(String redisKey, Class<T> clazz, AbstractCache abstractCache, int timeSeconds) {
        String cacheStr = stringRedisTemplate.opsForValue().get(redisKey);
        if(StringUtils.isNotEmpty(cacheStr)) {
            return JSONObject.parseArray(cacheStr, clazz);
        }
        String param = abstractCache.getData();
        if(param == null) {
            return null;
        }
        setCache(redisKey, param, timeSeconds);
        return JSONObject.parseArray(param, clazz);
    }

    /**
     * 设置缓存数据
     * @param redisKey
     * @param param
     * @param timeSeconds
     */
    public void setCache(String redisKey, String param, int timeSeconds) {
        stringRedisTemplate.opsForValue().set(redisKey, param, timeSeconds, TimeUnit.SECONDS);
    }

    /**
     * 清理缓存数据
     * @param redisKey
     */
    public void removeCache(String redisKey) {
        stringRedisTemplate.delete(redisKey);
    }


    public interface AbstractCache {

        /**
         * 获取需要存储到缓存的数据
         * @return
         */
        String getData();

    }

}
