package com.muyu.common.cache.abs;

import com.muyu.common.cache.AtomicSequenceCache;
import com.muyu.common.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author DongZl
 * @description: 原子序列缓存抽象类
 * @Date 2024-4-1 下午 08:33
 */
public abstract class AtomicSequenceCacheAbs<K> implements AtomicSequenceCache<K> {

    @Autowired
    private RedisService redisService;

    /**
     * 获取存储的值
     * @param key 键
     * @return 值
     */
    @Override
    public Long get (K key) {
        Long cacheValue = this.redisService.getCacheObject(encode(key));
        if (cacheValue == null){
            Long data = getData(key);
            cacheValue = data == null ? 0L : data;
            this.redisService.setCacheObject(encode(key), cacheValue);
        }
        return cacheValue;
    }

    /**
     * 自增
     * @param key
     */
    @Override
    public Long increment (K key) {
        return this.increment(key, 1L);
    }

    /**
     * 自减
     *
     * @param key
     */
    @Override
    public Long decrement (K key) {
        return this.decrement(key, 1L);
    }

    /**
     * 增加数值
     *
     * @param key
     * @param number
     */
    @Override
    public Long increment (K key, Long number) {
        Long numberValue = redisService.getCacheObject(encode(key));
        if (numberValue == null){
            Long data = getData(key);
            data = data == null ? 0L : data;
            redisService.setCacheObject(encode(key), data);
        }
        return redisService.increment(encode(key), number);
    }

    /**
     * 减少数值
     *
     * @param key
     * @param number
     */
    @Override
    public Long decrement (K key, Long number) {
        Long numberValue = redisService.getCacheObject(encode(key));
        if (numberValue == null){
            Long data = getData(key);
            data = data == null ? 0L : data;
            redisService.setCacheObject(encode(key), data);
        }
        return redisService.decrement(encode(key), number);
    }

    /**
     * 编码
     *
     * @param key ID
     *
     * @return 键
     */
    @Override
    public String encode (K key) {
        return keyPre() + key;
    }

    public abstract Long getData(K key);
}
