package com.fs.system.cache.impl;

import com.fs.system.cache.IDictCacheService;
import com.fs.system.service.ISysDictDataService;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.apache.http.util.Asserts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 系统字典数据缓存服务实现类
 *
 * @author xdd
 * @version 1.0
 * @since 2024-03-07
 */
@Service
public class SysDictDataCacheServiceImpl implements IDictCacheService {
    /**
     * 使用Caffeine本地缓存
     * maximumSize: 最大缓存条数
     * expireAfterWrite: 写入后多久过期（分钟）
     */
    private static final Cache<CompositeKey, String> CACHE = Caffeine.newBuilder()
            .maximumSize(3000)
            .expireAfterWrite(3, TimeUnit.MINUTES)
            .build();

    /**
     * 注入ISysDictDataService，用于缓存未命中时查询数据
     */
    @Autowired
    private ISysDictDataService sysDictDataService;

    /**
     * 根据字典类型和字典值查询字典标签
     *
     * @param dictType  字典类型
     * @param dictValue 字典值
     * @return 字典标签
     */
    @Override
    public String selectDictLabel(String dictType, String dictValue) {
        Asserts.notBlank(dictType,"字典类型不能为空!");
        Asserts.notBlank(dictValue,"字典值不能为空!");

        return CACHE.get(new CompositeKey(dictType, dictValue),
                e-> sysDictDataService.selectDictLabel(dictType,dictValue));
    }
    /**
     * 组合键，用于缓存的键
     */
    static class CompositeKey{
        /**
         * 字典类型
         */
        private final String dictType;
        /**
         * 字典值
         */
        private final String dictValue;

        public CompositeKey(String dictType, String dictValue) {
            this.dictType = dictType;
            this.dictValue = dictValue;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            CompositeKey that = (CompositeKey) o;
            return Objects.equals(dictType, that.dictType) && Objects.equals(dictValue, that.dictValue);
        }

        @Override
        public int hashCode() {
            return Objects.hash(dictType, dictValue);
        }
    }
}
