package com.community.commom.redis;



import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.JedisPool;

import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * redis 工具虚类
 * @author gengxiang
 * @create 2017-09-06 18:04
 *
 **/
public abstract class RedisTemplate {

    final Charset defaultCharset = Charset.forName("UTF8");

    long maxLockTime = 5000L;

    long lockRetryTime = 100L;

    @Autowired
    RedisSerializer serializer;

    @Autowired
    JedisPool redisPool;


    public Charset getDefaultCharset() {
        return defaultCharset;
    }

    public long getMaxLockTime() {
        return maxLockTime;
    }

    public void setMaxLockTime(long maxLockTime) {
        this.maxLockTime = maxLockTime;
    }

    public long getLockRetryTime() {
        return lockRetryTime;
    }

    public void setLockRetryTime(long lockRetryTime) {
        this.lockRetryTime = lockRetryTime;
    }

    public RedisSerializer getSerializer() {
        return serializer;
    }

    public void setSerializer(RedisSerializer serializer) {
        this.serializer = serializer;
    }

    public JedisPool getRedisPool() {
        return redisPool;
    }

    public void setRedisPool(JedisPool redisPool) {
        this.redisPool = redisPool;
    }

    /**
     * Set the value of a key
     *
     * @param key   key
     * @param value value
     * @return result
     */
    public abstract String set(String key, Object value);

    /**
     * setnx the value of a key
     *
     * @param key   key
     * @param value value
     * @return result
     */
    public abstract Long setnx(String key, Object value);

    /**
     * set an expire time for a key
     *
     * @param key     key
     * @param seconds expire time
     * @return result
     */
    public abstract Long expire(String key, int seconds);

    public abstract Long ttl(String key);

    /**
     * get a String value of a key
     *
     * @param key key
     * @return object
     */
    public abstract String get(String key);

    /**
     * get an object of a key
     *
     * @param key    key
     * @param tClass the class of object
     * @param <T>    generic type
     * @return object
     */
    public abstract <T> T get(String key, Class<T> tClass);

    /**
     * delete a value of a key
     *
     * @param key key
     * @return result
     */
    public abstract Long del(String key);

    /**
     * delete values of keys
     *
     * @param keys keys
     * @return result
     */
    public abstract Long del(String... keys);

    /**
     * Set the value of a hash field
     *
     * @param key   key
     * @param field hash field
     * @param value value
     * @return result
     */
    public abstract Long hset(String key, String field, Object value);

    /**
     * Set the values of fields
     *
     * @param key key
     * @param map key:field,value:object
     * @return result
     */
    public abstract <T> String hmset(String key, Map<String, T> map);

    public abstract <T> Map<String, T> hmget(String key, List<String> fields, Class<T> tClass);

    /**
     * del the value of a hash field
     *
     * @param key   key
     * @param field hash field
     * @return result
     */
    public abstract Long hdel(String key, String field);

    /**
     * Set the string value of a hash field
     *
     * @param key    key
     * @param field  hash field
     * @param tClass generics class type
     * @param <T>    generics class
     * @return value
     */
    public abstract <T> T hget(String key, String field, Class<T> tClass);


    /**
     * Set the string value of a hash field
     *
     * @param key    key
     * @param tClass generics class type
     * @param <T>    generics class
     * @return value
     */
    public abstract <T> Map<String,T> hgetAll(String key, Class<T> tClass);

    /**
     * Get all the fields in a hash
     *
     * @param key key
     * @return all the fields set
     */
    public abstract Set<String> hkeys(String key);


    /**
     * Get a range of elements from a list
     *
     * @param key    key
     * @param tClass generic class type
     * @param start  start number, the first is 0
     * @param stop   stop number, the last is -1
     * @param <T>    generic class
     * @return list of results
     */
    public abstract <T> List<T> lrange(String key, Class<T> tClass, long start, long stop);

    /**
     * Get all of elements from a list
     *
     * @param key    key
     * @param tClass generic class type
     * @param <T>    generic class
     * @return list of results
     */
    public abstract <T> List<T> lrange(String key, Class<T> tClass);

    /**
     * Prepend one or multiple values to a list
     *
     * @param key    key
     * @param values values
     * @return result
     */
    public abstract Long lpush(String key, Object... values);

    /**
     * Prepend one or multiple values to a list
     *
     * @param key    key
     * @param values values
     * @return result
     */
    public abstract Long lpush(String key, List values);

    /**
     * Append one or multiple values to a list
     *
     * @param key    key
     * @param values values
     * @return result
     */
    public abstract Long rpush(String key, Object... values);

    /**
     * Append one or multiple values to a list
     *
     * @param key    key
     * @param values values
     * @return result
     */
    public abstract Long rpush(String key, List values);

    /**
     * get a lock for key
     *
     * @param key key
     * @return result
     */
    public abstract Boolean getLock(String key);

    /**
     * release lock
     *
     * @param key key
     */
    public abstract void releaseLock(String key);

    /**
     * 缓存是否存在
     *
     * @param key 键
     * @return
     */
    public abstract boolean exists(String key);

    /**
     * 缓存是否存在
     *
     * @param key   键
     * @param field
     * @return
     */
    public abstract boolean hexists(String key, String field);

    /**
     * 获取hash缓存的个数
     *
     * @param key   键
     * @return
     */
    public abstract Long hlen(String key);

    /**
     * 计数器递减
     *
     * @param key
     * @return
     */
    public abstract Long decr(String key);

    /**
     * 计数器递增
     *
     * @param key
     * @return
     */
    public abstract Long incr(String key);

	/**
	 * map值加
	 * @param key
	 * @param field
	 * @param value
	 * @return
	 */
	public abstract  Long hincrBy(final String key, final String field, final long value);

}
