package com.ssyf.plugs.cache.service.impl;

import com.ssyf.plugs.cache.helper.CacheHelper;
import com.ssyf.plugs.cache.service.CacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * ehcache本地缓存服务类
 * @author huwei
 * @date 2023/9/21 14:55
 */
@Slf4j
@Service
@ConditionalOnBean(EhCacheCacheManager.class)
public class EhcacheCacheService implements CacheService {

    @Autowired
    private EhCacheCacheManager ehCacheCacheManager;
    /**
     * 记录key值的缓存key
     */
    private static final String RECORD_KEY_NAME = "@@@@RECORD_KEY_NAME@@@@";

    /**
     * 记录缓存的过期时间
     */
    private static final long RECORD_KEY_CACHE_TIME_OUT = Long.MAX_VALUE;

    @Override
    public <T> T put(long timeoutSecond, String key, T obj, String... prefix) {
        if(obj != null) {
            String realKey = wrapKey(key, prefix);
            CacheHelper.getOrCreateCache(parseAndGetPrefix(prefix) ,this.ehCacheCacheManager).put(realKey, CacheHelper.wrapValue(obj));
            log.debug("[cache]cache value,key={},value={}" ,realKey ,obj);
            //缓存key值
            recordKey(key ,prefix);
            return obj;
        }
        return null;
    }

    @Override
    public <T> T get(String key, String... prefix) {
        String realKey = wrapKey(key, prefix);
        Object object = CacheHelper.getOrCreateCache(parseAndGetPrefix(prefix) ,this.ehCacheCacheManager).get(realKey);
        log.debug("[cache]get cache,key={},value={}" ,realKey ,object);
        return CacheHelper.parseValue(object);
    }

    @Override
    public Set<String> keys(String... prefix) {
        Set<String> keys = get(RECORD_KEY_NAME);
        if(keys == null || keys.size() == 0){
            return Collections.EMPTY_SET;
        }
        String realPrefix = parseAndGetPrefix(prefix);
        return keys.stream().filter(key->key.startsWith(realPrefix)).collect(Collectors.toSet());
    }

    @Override
    public boolean isExists(String key, String... prefix) {
        Set<String> keys = get(RECORD_KEY_NAME);
        return keys != null && keys.contains(wrapKey(key, prefix));
    }

    @Override
    public boolean remove(String key, String... prefix) {
        String realKey = wrapKey(key, prefix);
        CacheHelper.getOrCreateCache(parseAndGetPrefix(prefix) ,this.ehCacheCacheManager).evict(realKey);
        log.debug("[cache]remove cache,key={}" ,realKey);
        removeKey(key,prefix);
        return true;
    }

    @Override
    public boolean clearPrefix(String... prefix) {
        String realPrefix = parseAndGetPrefix(prefix);
        CacheHelper.getOrCreateCache(realPrefix ,this.ehCacheCacheManager).clear();
        log.debug("[cache]clear cache,prefix={}" ,realPrefix);
        return true;
    }

    /**
     * 记录key值
     * @param key
     * @param prefix
     */
    private void recordKey(String key ,String ...prefix){
        //去循环调用
        if(RECORD_KEY_NAME.equals(key)){
            return;
        }
        Set<String> keys = get(RECORD_KEY_NAME);
        if(keys == null){
            keys = new HashSet<>();
        }
        keys.add(wrapKey(key ,prefix));
        //缓存
        put(RECORD_KEY_CACHE_TIME_OUT ,RECORD_KEY_NAME ,keys);
    }

    /**
     * 删除缓存的key值
     * @param key
     * @param prefix
     */
    private void removeKey(String key ,String ...prefix){
        Set<String> keys = get(RECORD_KEY_NAME);
        if(keys != null){
            keys.remove(wrapKey(key ,prefix));
            //缓存
            put(RECORD_KEY_CACHE_TIME_OUT ,RECORD_KEY_NAME ,keys);
        }
    }
}
