package com.publiccms.common.redis;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.publiccms.common.tools.CommonUtils;

import redis.clients.jedis.RedisClient;

/**
 * RedisClientOperational
 */
public class RedisClientOperational {
    /**
     * 
     */
    public static final int DEFAULT_EXPIRY_IN_SECONDS = 120;

    protected final Log log = LogFactory.getLog(getClass());
    private RedisClient redisClient;
    private Map<String, RedisCacheEntity<Object, Object>> regionMap = new HashMap<>();

    /**
     * @param redisClient 
     */
    public RedisClientOperational(RedisClient redisClient) {
        this.redisClient = redisClient;
    }

    /**
     * @return
     */
    public long dbSize() {
        return redisClient.dbSize();
    }

    /**
     * @param region
     * @param key
     * @return
     */
    public boolean exists(String region, Object key) {
        return createOrGetCache(region).contains(key.toString());
    }

    /**
     * @param region
     * @param key
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> T get(String region, Object key) {
        T cacheItem = (T) createOrGetCache(region).get(key.toString());
        log.trace(CommonUtils.joinString("retrieve cache item. region=", region, ", key=", key, ", value=", cacheItem));
        return cacheItem;
    }

    /**
     * @param region
     * @param key
     * @param value
     */
    public void set(String region, Object key, Object value) {
        set(region, key, value, null);
    }

    /**
     * @param region
     * @param key
     * @param value
     * @param expiry
     */
    public void set(String region, Object key, Object value, Long expiry) {
        log.trace(CommonUtils.joinString("set cache item. region=", region, ", key=", key, ", timeout=",
                (CommonUtils.empty(expiry) ? 0 : expiry)));
        createOrGetCache(region).put(key.toString(), value, expiry);
    }

    /**
     * @param region
     * @param key
     * @return
     */
    public Object del(String region, Object key) {
        return createOrGetCache(region).remove(key.toString());
    }

    /**
     * @param region
     */
    public void clearRegion(String region) {
        createOrGetCache(region).clear(false);
    }

    /**
     * @param region
     */
    public void removeRegion(String region) {
        regionMap.remove(region);
    }

    /**
     * @param region
     * @return
     */
    public RedisCacheEntity<Object, Object> createOrGetCache(String region) {
        return regionMap.computeIfAbsent(region, k -> new RedisCacheEntity<>().init(k, redisClient));
    }

    public void close() {
        redisClient.close();
    }
}
