package com.brilliance.mda.support.cache.impl;

import com.brilliance.mda.support.cache.ICache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.util.UUID;

public class GuavaCache<V> implements ICache<String, V> {

    private final Logger logger = LoggerFactory.getLogger(GuavaCache.class);

    private final LoadingCache<String, V> cache;
    private String cacheName;

    public GuavaCache(String cacheName, long seconds) {
        this.cacheName = cacheName;
        cache = CacheBuilder.newBuilder()
                .expireAfterAccess(Duration.ofSeconds(seconds))
                .build(new CacheLoader<String, V>() {
                    @Override
                    public V load(String s) throws Exception {
                        return null;
                    }
                });
    }

    @Override
    public String store(V v) {
        String key = generateKey();
        cache.put(key, v);
        return key;
    }

    @Override
    public void store(String key, V v) {
        cache.put(key, v);
    }

    @Override
    public V get(String k) {
        try {
            return cache.get(k);
        } catch (Exception e) {
            logger.warn("Acquire {} cache failed", cacheName);
        }
        return null;
    }

    @Override
    public void remove(String k) {
        cache.invalidate(k);
    }

    @Override
    public String generateKey() {
        return UUID.randomUUID().toString();
    }

    @Override
    public void cleanup() {
        logger.info("{} clean up start.size:{}",this.cacheName,cache.size());
        this.cache.cleanUp();
        logger.info("{} clean up over.size:{}",this.cacheName,cache.size());
    }

    @Override
    public boolean contains(String key) {
        return this.get(key) != null;
    }
}
