package com.scpyun.base.core.utils;

import com.scpyun.base.core.bean.JedisType;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.exceptions.JedisException;
import redis.clients.util.SafeEncoder;

import java.util.*;


public class JedisImplUtils {

    private static JedisPool jedisPool = null;

    private static JedisSentinelPool jedisSentinelPool = null;

    private static JedisPool jedisPoolByLogin = null;

    private static JedisSentinelPool jedisPoolByLoginForSentinel = null;

    public static final String SENTINEL_ONLY = Global.getConfig("scp.sentinel.only");

    static {
        try {
            redis.clients.jedis.JedisPoolConfig jedisPoolConfig = new redis.clients.jedis.JedisPoolConfig();
            jedisPoolConfig.setMaxIdle(Integer.parseInt(Global.getConfig("scp.login.redis.maxIdle")));
            jedisPoolConfig.setMaxTotal(Integer.parseInt(Global.getConfig("scp.login.redis.maxTotal")));
            jedisPoolConfig.setTestOnBorrow(true);
            if ("true".equals(SENTINEL_ONLY)) {
                jedisPoolByLoginForSentinel = SpringContextHolder.getBean(JedisSentinelPool.class);
            } else {
                jedisPoolByLogin = new JedisPool(jedisPoolConfig,
                        Global.getConfig("scp.redis.host"),
                        Integer.parseInt(Global.getConfig("scp.redis.port")),
                        3000,
                        Global.getConfig("scp.redis.password"),
                        15);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * redis过期时间,以秒为单位
     */
    public final static int HALF_HOUR = 30*60;          //30分钟
    public final static int QUARTER_HOUR = 60*60;       //45分钟
    public final static int EXRP_HOUR = 60*60;          //一小时
    public final static int EXRP_DAY = 60*60*24;        //一天
    public final static int EXRP_MONTH = 60*60*24*30;   //一个月

    //这个 timeout 是到 redis 的连接的超时时间
    private static final int TIMEOUT = 30*60;

    /**
     * redis 是否被实例化
     * @return
     */
    public static boolean exist(){
        return false;
    }

    /**
     * 获取缓存
     * @param key 键
     * @return 值
     */
    public static String get(String key) {
        String value = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(key)) {
                value = jedis.get(key);
                value = value !=null && !"nil".equalsIgnoreCase(value) ? value : null;
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return value;
    }

    public static String get(String key, JedisType jedisType) {
        String value = null;
        Jedis jedis = null;
        try {
            jedis = getResourceByLogin();
            if (jedis.exists(key)) {
                value = jedis.get(key);
                value = value !=null && !"null".equalsIgnoreCase(value) ? value : null;
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis,jedisType);
        }
        return value;
    }

    /**
     * 获取缓存
     * @param key 键
     * @return 值
     */
    public static byte[] get(byte[] key) {
        byte[] value = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(key)) {
                value = jedis.get(key);
                value = value !=null ? value : null;
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return value;
    }


    /**
     * 获取缓存
     * @param key 键
     * @return 值
     */
    public static Object getObject(String key) {
        Object value = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(getBytesKey(key))) {
                value = toObject(jedis.get(getBytesKey(key)));
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return value;
    }

    public static Object getObject(String key, Enum jedisType) {
        Object value = null;
        Jedis jedis = null;
        try {
            jedis = getResourceByLogin();
            if (jedis.exists(getBytesKey(key))) {
                value = toObject(jedis.get(getBytesKey(key)));
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis, jedisType);
        }
        return value;
    }


    /**
     * 获取缓存
     * @param key 键
     * @param index db_index键
     * @return 值
     */
    public static Object getObject(String key,int index) {
        Object value = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            select(jedis, index);
            if (jedis.exists(getBytesKey(key))) {
                value = toObject(jedis.get(getBytesKey(key)));
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return value;
    }


    /**
     * 设置缓存
     * @param key 键
     * @param value 值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String set(String key, String value, int cacheSeconds) {
        String result = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.set(key, value);
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    public static String set(String key, String value, int cacheSeconds, JedisType jedisType) {
        String result = null;
        Jedis jedis = null;
        try {
            jedis = getResourceByLogin();
            result = jedis.set(key, value);
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis,jedisType);
        }
        return result;
    }

    public static Long zadd(String key, Double score, int cacheSeconds, String member) {
        Long result = null;
        Jedis jedis = null;
        try {
            jedis = getResourceByLogin();
            result = jedis.zadd(key, score, member);
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    public static Set<String> zrevrange(String key, Long start, Long end) {
        Set<String> result = null;
        Jedis jedis = null;
        try {
            jedis = getResourceByLogin();
            result = jedis.zrevrange(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return result;
    }


    public static Long zrem(String key,String member) {
        Long result = null;
        Jedis jedis = null;
        try {
            jedis = getResourceByLogin();
            result = jedis.zrem(key, member);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 设置缓存
     * @param key 键
     * @param value 值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String setObject(String key, Object value, int cacheSeconds) {
        String result = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.set(getBytesKey(key), toBytes(value));
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 设置缓存
     * @param key 键
     * @param value 值
     * @param index db_index值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String setObject(String key, Object value, int cacheSeconds,int index) {
        String result = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            select(jedis,index);
            result = jedis.set(getBytesKey(key), toBytes(value));
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }




    /**
     * 获取List缓存
     * @param key 键
     * @return 值
     */
    public static List<String> getList(String key) {
        List<String> value = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(key)) {
                value = jedis.lrange(key, 0, -1);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return value;
    }

    /**
     * 获取List缓存
     * @param key 键
     * @return 值
     */
    public static List<Object> getObjectList(String key) {
        List<Object> value = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(getBytesKey(key))) {
                List<byte[]> list = jedis.lrange(getBytesKey(key), 0, -1);
                value = new ArrayList<Object>();
                for (byte[] bs : list){
                    value.add(toObject(bs));
                }
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return value;
    }

    /**
     * 设置List缓存
     * @param key 键
     * @param value 值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static long setList(String key, List<String> value, int cacheSeconds) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(key)) {
                jedis.del(key);
            }
            result = jedis.rpush(key, (String[])value.toArray());
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 设置List缓存
     * @param key 键
     * @param value 值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static long setObjectList(String key, List<Object> value, int cacheSeconds) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(getBytesKey(key))) {
                jedis.del(key);
            }
            List<byte[]> list = new ArrayList<byte[]>();
            for (Object o : value){
                list.add(toBytes(o));
            }
            result = jedis.rpush(getBytesKey(key), (byte[][])list.toArray());
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 向List缓存中添加值
     * @param key 键
     * @param value 值
     * @return
     */
    public static long listAdd(String key, String... value) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.rpush(key, value);
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 向List缓存中添加值
     * @param key 键
     * @param value 值
     * @return
     */
    public static long listObjectAdd(String key, Object... value) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            List<byte[]> list = new ArrayList<byte[]>();
            for (Object o : value){
                list.add(toBytes(o));
            }
            result = jedis.rpush(getBytesKey(key), (byte[][])list.toArray());
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 向List缓存中添加值
     * @param key 键
     * @param value 值
     * @return
     */
    public static long setQueue(String key, String... value) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.rpush(key, value);
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 向List缓存中添加值
     * @param key 键
     * @return
     */
    public static String getQueue(String key) {
        String result = "";
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.lpop(key);
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 获取缓存
     * @param key 键
     * @return 值
     */
    public static Set<String> getSet(String key) {
        Set<String> value = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(key)) {
                value = jedis.smembers(key);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return value;
    }

    /**
     * 获取缓存
     * @param key 键
     * @return 值
     */
    public static Set<Object> getObjectSet(String key) {
        Set<Object> value = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(getBytesKey(key))) {
                value = new HashSet<Object>();
                Set<byte[]> set = jedis.smembers(getBytesKey(key));
                for (byte[] bs : set){
                    value.add(toObject(bs));
                }
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return value;
    }

    /**
     * 设置Set缓存
     * @param key 键
     * @param value 值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static long setSet(String key, Set<String> value, int cacheSeconds) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(key)) {
                jedis.del(key);
            }
            result = jedis.sadd(key, (String[])value.toArray());
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 设置Set缓存
     * @param key 键
     * @param value 值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static long setObjectSet(String key, Set<Object> value, int cacheSeconds) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(getBytesKey(key))) {
                jedis.del(key);
            }
            Set<byte[]> set = new HashSet<byte[]>();
            for (Object o : value){
                set.add(toBytes(o));
            }
            result = jedis.sadd(getBytesKey(key), (byte[][])set.toArray());
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 向Set缓存中添加值
     * @param key 键
     * @param value 值
     * @return
     */
    public static long setSetAdd(String key, String... value) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.sadd(key, value);
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 向Set缓存中添加值
     * @param key 键
     * @param value 值
     * @return
     */
    public static long setSetObjectAdd(String key, Object... value) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            Set<byte[]> set = new HashSet<byte[]>();
            for (Object o : value){
                set.add(toBytes(o));
            }
            result = jedis.rpush(getBytesKey(key), (byte[][])set.toArray());
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 获取Map缓存
     * @param key 键
     * @return 值
     */
    public static Map<String, String> getMap(String key) {
        Map<String, String> value = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(key)) {
                value = jedis.hgetAll(key);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return value;
    }

    public static Map<String, String> getMap(String key, Enum jedisType) {
        Map<String, String> value = null;
        Jedis jedis = null;
        try {
            jedis = getResourceByLogin();
            if (jedis.exists(key)) {
                value = jedis.hgetAll(key);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis, jedisType);
        }
        return value;
    }

    /**
     * 获取Map缓存
     * @param key 键
     * @return 值
     */
    public static Map<String, Object> getObjectMap(String key) {
        Map<String, Object> value = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(getBytesKey(key))) {
                value = new HashMap<String, Object>();
                Map<byte[], byte[]> map = jedis.hgetAll(getBytesKey(key));
                for (Map.Entry<byte[], byte[]> e : map.entrySet()){
                    value.put(String.valueOf(e.getKey()), toObject(e.getValue()));
                }
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return value;
    }

    /**
     * 设置Map缓存
     * @param key 键
     * @param value 值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String setMap(String key, Map<String, String> value, int cacheSeconds) {
        String result = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(key)) {
                jedis.del(key);
            }
            result = jedis.hmset(key, value);
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 设置Map缓存
     * @param key 键
     * @param value 值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String setObjectMap(String key, Map<String, Object> value, int cacheSeconds) {
        String result = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(getBytesKey(key))) {
                jedis.del(key);
            }
            Map<byte[], byte[]> map = new HashMap<byte[], byte[]>();
            for (Map.Entry<String, Object> e : value.entrySet()){
                map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));
            }
            result = jedis.hmset(getBytesKey(key), (Map<byte[], byte[]>)map);
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 向Map缓存中添加值
     * @param key 键
     * @param value 值
     * @return
     */
    public static String mapPut(String key, Map<String, String> value) {
        String result = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.hmset(key, value);
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 向Map缓存中添加值
     * @param key 键
     * @param value 值
     * @return
     */
    public static String mapObjectPut(String key, Map<String, Object> value) {
        String result = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            Map<byte[], byte[]> map = new HashMap<byte[], byte[]>();
            for (Map.Entry<String, Object> e : value.entrySet()){
                map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));
            }
            result = jedis.hmset(getBytesKey(key), (Map<byte[], byte[]>)map);
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 移除Map缓存中的值
     * @param key 键
     * @return
     */
    public static long mapRemove(String key, String mapKey) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.hdel(key, mapKey);
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 移除Map缓存中的值
     * @param key 键
     * @return
     */
    public static long mapObjectRemove(String key, String mapKey) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.hdel(getBytesKey(key), getBytesKey(mapKey));
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 判断Map缓存中的Key是否存在
     * @param key 键
     * @return
     */
    public static boolean mapExists(String key, String mapKey) {
        boolean result = false;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.hexists(key, mapKey);
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 判断Map缓存中的Key是否存在
     * @param key 键
     * @return
     */
    public static boolean mapObjectExists(String key, String mapKey) {
        boolean result = false;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.hexists(getBytesKey(key), getBytesKey(mapKey));
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 删除缓存
     * @param key 键
     * @return
     */
    public static long del(String key) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(key)){
                result = jedis.del(key);
            }else{
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 批量删除缓存
     * @return 删除的记录数
     */
    public static long del(String... keys) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.del(keys);
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 批量删除缓存
     * @return 删除的记录数
     */
    public static long del(byte[]... keys) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.del(keys);
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 对List,Set,SortSet进行排序,如果集合数据较大应避免使用这个方法
     * @param key
     * @return
     */
    public static List<String> sort(String key){
        Jedis jedis = null;
        List<String> list = null;
        try{
            jedis = getResource();
            list = jedis.sort(key);
        }catch(Exception e){
        }finally{
            returnResource(jedis);
        }

        return list;
    }

    /**
     * 更改key
     * @param oldkey
     * @param newkey
     * @return
     */
    public static String rename(String oldkey, String newkey){
        Jedis jedis = null;
        String code = null;
        try{
            jedis = getResource();
            code = jedis.rename(SafeEncoder.encode(oldkey), SafeEncoder.encode(newkey));
        }catch(Exception e){
        }finally{
            returnResource(jedis);
        }
        return code;
    }
    /**
     * 更改key,仅当新key不存在时才执行
     * @param oldkey
     * @param newkey
     * @return Integer reply, specifically: 1 if the key was renamed 0 if the target key already exist
     */
    public static Long renamex(String oldkey, String newkey){
        Jedis jedis = null;
        long result = 0;
        try{
            jedis = getResource();
            result = jedis.renamenx(oldkey, newkey);
        }catch(Exception e){
        }finally{
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 设置key的过期时间，以秒为单位
     * @param key
     * @param seconds
     * @return 影响的记录数
     */
    public static Long expired(String key, int seconds){
        long result = 0;
        Jedis jedis = null;
        try{
            jedis = getResource();
            result = jedis.expire(key, seconds);
        }catch(Exception e){
        }finally{
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 设置key的过期时间,它是距历元（即格林威治标准时间 1970 年 1 月 1 日的 00:00:00，格里高利历）的偏移量
     * @param key
     * @param timestamp
     * @return 影响的记录数
     */
    public static Long expireAt(String key, long timestamp){
        long result = 0;
        Jedis jedis = null;
        try{
            jedis = getResource();
            result = jedis.expireAt(key, timestamp);
        }catch(Exception e){
        }finally{
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 查询key的过期时间
     * @param key
     * @return 以秒为单位的时间表示
     */
    public static Long ttl(String key){
        long result = 0;
        Jedis jedis = null;
        try{
            jedis = getResource();
            result = jedis.ttl(key);
        }catch(Exception e){
        }finally{
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 取消对key过期时间的设置
     * @param key
     * @return 影响的记录数
     */
    public static Long persist(String key){
        long result = 0;
        Jedis jedis = null;
        try{
            jedis = getResource();
            result = jedis.persist(key);
        }catch(Exception e){
        }finally{
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 查找所有匹配给定的模式的键
     * @param pattern key的表达式,*表示多个，？表示一个
     * @return
     */
    public static Set<String> keys(String pattern){
        Set<String> result = null;
        Jedis jedis = null;
        try{
            jedis = getResource();
            result = jedis.keys(pattern);
        }catch(Exception e){
        }finally{
            returnResource(jedis);
        }
        return result;
    }


    /**
     * 删除缓存
     * @param key 键
     * @return
     */
    public static long delObject(String key) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            if (jedis.exists(getBytesKey(key))){
                result = jedis.del(getBytesKey(key));
            }else{
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 删除缓存
     * @param key 键
     * @return
     */
    public static long delObject(String key,int index) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            select(jedis, index);
            if (jedis.exists(getBytesKey(key))){
                result = jedis.del(getBytesKey(key));
            }else{
            }
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }



    /**
     * 缓存是否存在
     * @param key 键
     * @return
     */
    public static boolean exists(String key) {
        boolean result = false;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.exists(key);
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 缓存是否存在
     * @param key 键
     * @return
     */
    public static boolean existsObject(String key) {
        boolean result = false;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.exists(getBytesKey(key));
        } catch (Exception e) {
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 获取资源
     * @return
     * @throws JedisException
     */
    public static Jedis getResource() throws JedisException {
        Jedis jedis = null;
        if ("true".equals(SENTINEL_ONLY)) {
            try {
                if(jedisSentinelPool == null){
                    jedisSentinelPool = SpringContextHolder.getBean(JedisSentinelPool.class);
                }
                jedis = jedisSentinelPool.getResource();
            } catch (JedisException e) {
                e.printStackTrace();
                returnBrokenResource(jedis);
                throw e;
            }
            return jedis;
        } else {
            try {
                if(jedisPool == null){
                    jedisPool = SpringContextHolder.getBean(JedisPool.class);
                }
                jedis = jedisPool.getResource();
            } catch (JedisException e) {
                e.printStackTrace();
                returnBrokenResource(jedis);
                throw e;
            }
            return jedis;
        }

    }

    public static Jedis getResourceByLogin() throws JedisException {
        Jedis jedis = null;
        if ("true".equals(SENTINEL_ONLY)) {
            try {
                if(jedisPoolByLoginForSentinel == null){
                    jedisPoolByLoginForSentinel = SpringContextHolder.getBean(JedisSentinelPool.class);
                }
                jedis = jedisPoolByLoginForSentinel.getResource();
            } catch (JedisException e) {
                e.printStackTrace();
                returnBrokenResource(jedis, 1);
                throw e;
            }
            return jedis;
        } else {
            try {
                if(jedisPoolByLogin == null){
                    jedisPoolByLogin = SpringContextHolder.getBean(JedisPool.class);
                }
                jedis = jedisPoolByLogin.getResource();
            } catch (JedisException e) {
                e.printStackTrace();
                returnBrokenResource(jedis, 1);
                throw e;
            }
            return jedis;
        }
    }

    /**
     * 归还资源
     * @param jedis
     */
    public static void returnBrokenResource(Jedis jedis) {
        if (jedis != null) {
            if ("true".equals(SENTINEL_ONLY)) {
                jedisSentinelPool.returnBrokenResource(jedis);
            } else {
                jedisPool.returnBrokenResource(jedis);
            }

        }
    }

    public static void returnBrokenResource(Jedis jedis, int type) {
        if (jedis != null) {
            if ("true".equals(SENTINEL_ONLY)) {
                jedisPoolByLoginForSentinel.returnBrokenResource(jedis);
            } else {
                jedisPoolByLogin.returnBrokenResource(jedis);
            }
        }
    }

    /**
     * 释放资源
     * @param jedis
     */
    public static void returnResource(Jedis jedis) {
        if (jedis != null) {
            if (SENTINEL_ONLY.equals("true")) {
                jedisSentinelPool.returnResource(jedis);
            } else {
                jedisPool.returnResource(jedis);
            }
        }
    }

    public static void returnResource(Jedis jedis, Enum jedisType) {
        if (jedis != null) {
            jedisPoolByLogin.returnResource(jedis);
        }
    }

    /**
     * 获取byte[]类型Key
     * @return
     */
    public static byte[] getBytesKey(Object object){
        if(object instanceof String){
            return ((String)object).getBytes();
        }else{
            // TOFO
            return ObjectUtils.serialize(object);
        }
    }

    /**
     * 删除原有key并且重新设值
     * @param key
     * @param cacheSeconds
     */
    public static String resetObjectByKey(String key,Object value,int cacheSeconds){
        Jedis jedis = null;
        String result = "";
        try {
            jedis = getResource();
            jedis.del(key);
            result = jedis.set(getBytesKey(key), toBytes(value));
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (JedisException e) {
            returnBrokenResource(jedis);
            throw e;
        }
        return result;
    }


    /**
     * Object转换byte[]类型
     * @return
     */
    public static byte[] toBytes(Object object){
        return  ObjectUtils.serialize(object);
    }

    /**
     * byte[]型转换Object
     * @return
     */
    public static Object toObject(byte[] bytes){
        return ObjectUtils.unserialize(bytes);
    }

    /**
     * 返回当前数据库的 key 的数量
     * @return
     */
    public static long dbSize(){
        long result = 0;
        Jedis jedis = null;
        try{
            jedis = getResource();
            jedis.select(jedis.getDB().intValue());
            result = jedis.dbSize();
        }catch(Exception e){

        }finally{
            returnResource(jedis);
        }
        return result;
    }


    /**
     * 返回当前数据库的 key 的数量
     * @return
     */
    public static long dbSize(int index){
        long result = 0;
        Jedis jedis = null;
        try{
            jedis = getResource();
            select(jedis, index);
            jedis.select(jedis.getDB().intValue());
            result = jedis.dbSize();
        }catch(Exception e){

        }finally{
            returnResource(jedis);
        }
        return result;
    }


    /**
     * 清空当前数据库
     * @return
     */
    public static String flushDB(int index){
        String result = "";
        Jedis jedis = null;
        try{
            jedis = getResource();
            select(jedis,index);
            result = jedis.flushDB();
        }catch(Exception e){

        }finally{
            returnResource(jedis);
        }
        return result;
    }

    /**
     * 选择数据库
     * @param index
     * @return Status code reply
     */
    public static String select(Jedis jedis,int index){
        if(index < 0 || index > 9){
            index = 0;
        }
        return jedis.select(index);
    }



    /**
     * 清空所有数据库
     * @return
     */
    public static String flushALL(){
        String result = "";
        Jedis jedis = null;
        try{
            jedis = getResource();
            result = jedis.flushAll();
        }catch(Exception e){

        }finally{
            returnResource(jedis);
        }
        return result;
    }

    public static Long hset(final String key, final String field, final String value) {
        Jedis jedis = null;
        Long resultLong = null;
        try {
            jedis = getResource();
            resultLong = jedis.hset(key, field, value);
        } catch (JedisException e) {
            returnBrokenResource(jedis);
            throw e;
        } finally {
            returnResource(jedis);
        }
        return resultLong;
    }

    public static String hget(final String key, final String field) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = getResource();
            result = jedis.hget(key, field);
        } catch (JedisException e) {
            returnBrokenResource(jedis);
            throw e;
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    public static String hget(final String key, final String field, Enum jedisType) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = getResourceByLogin();
            result = jedis.hget(key, field);
        } catch (JedisException e) {
            returnBrokenResource(jedis, 1);
            throw e;
        } finally {
            returnResource(jedis, jedisType);
        }
        return result;
    }


    public static List<String> hvals(final String key) {
        Jedis jedis = null;
        try {
            jedis = getResource();
            return jedis.hvals(key);
        } catch (JedisException e) {
            returnBrokenResource(jedis);
            throw e;
        } finally {
            returnResource(jedis);
        }
    }

    public static Set<String> hkeys(final String key) {
        Jedis jedis = null;
        try {
            jedis = getResource();
            return jedis.hkeys(key);
        } catch (JedisException e) {
            returnBrokenResource(jedis);
            throw e;
        } finally {
            returnResource(jedis);
        }
    }

    public static Long hdel(final String key, final String... fields) {
        Jedis jedis = null;
        Long resultLong = null;
        try {
            jedis = getResource();
            resultLong = jedis.hdel(key, fields);
        } catch (JedisException e) {
            returnBrokenResource(jedis);
            throw e;
        } finally {
            returnResource(jedis);
        }
        return resultLong;
    }

    public static String rpoplpush(String queue, String tmpQueue) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = getResource();
            result = jedis.rpoplpush(queue, tmpQueue);
        } catch (JedisException e) {
            returnBrokenResource(jedis);
            throw e;
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    public static long lpush(final String key, final String... strings)  {
        Jedis jedis = null;
        long result = 0;
        try {
            jedis = getResource();
            result = jedis.lpush(key, strings);
        } catch (JedisException e) {
            returnBrokenResource(jedis);
            throw e;
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    public static String rpop(String queue) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = getResource();
            result = jedis.rpop(queue);
        } catch (JedisException e) {
            returnBrokenResource(jedis);
            throw e;
        } finally {
            returnResource(jedis);
        }
        return result;
    }

    public static Long incr(String key){
        Jedis jedis = null;
        Long result = 0l;
        try {
            jedis = getResource();
            result = jedis.incr(key);
        } catch (JedisException e) {
            returnBrokenResource(jedis);
            throw e;
        } finally {
            returnResource(jedis);
        }
        return result;
    }

//     /**
//     * GEO key  经度 纬度 名称
//     *
//     * @param key
//     * @param longitude
//     * @param latitude
//     * @param member
//     * @return
//     */
//    public static Long geoadd(String key, double longitude, double latitude, String member) {
//        Jedis jedis = null;
//        Long resultLong = null;
//        try {
//            jedis = getResource();
//            resultLong = jedis.geoadd(key, longitude, latitude, member);
//        } catch (JedisException e) {
//            returnBrokenResource(jedis);
//            throw e;
//        } finally {
//            returnResource(jedis);
//        }
//        return resultLong;
//    }
//
//    /**
//     * geo 查询地理位置
//     *
//     * @param key
//     * @param name 位置名
//     * @return
//     */
//    public static List<GeoCoordinate> geops(String key, String... name) {
//        Jedis jedis = null;
//        List<GeoCoordinate> result = new ArrayList<>();
//        try {
//            jedis = getResource();
//            result = jedis.geopos(key, name);
//        } catch (JedisException e) {
//            returnBrokenResource(jedis);
//            throw e;
//        } finally {
//            returnResource(jedis);
//        }
//        return result;
//    }
//
//    /**
//     * 用于获取两个地理位置间的距离
//     * unit m 表示单位为米；
//     * km 表示单位为千米；
//     * mi 表示单位为英里；
//     * ft 表示单位为英尺。
//     * pS: 计算举例时存在 0.5% 左右的误差，这是由于 Redis GEO 把地球假设成了完美的球体
//     *
//     * @return
//     */
//    public static Double geoDist(String key, String city1, String city2, GeoUnit unit) {
//        Jedis jedis = null;
//        Double result = null;
//        try {
//            jedis = getResource();
//            result = jedis.geodist(key, city1, city2, unit);
//        } catch (JedisException e) {
//            returnBrokenResource(jedis);
//            throw e;
//        } finally {
//            returnResource(jedis);
//        }
//        return result;
//    }
//
//    /**
//     * 以给定的经纬度为中心，计算出 key 包含的地理位置元素与中心的距离不超过给定最大距离的所有位置元素
//     * GeoRadiusParam 参数说明：
//     * WITHDIST ：在返回位置元素的同时， 将位置元素与中心之间的距离也一并返回。
//     * WITHCOORD ：返回位置元素的经度和维度。
//     * WITHHASH ：采用 GEOHASH 对位置元素进行编码，以 52 位有符号整数的形式返回有序集合的分值，该选项主要用于底层调试，实际作用不大。
//     * COUNT：指定返回位置元素的数量，在数据量非常大时，可以使用此参数限制元素的返回数量，从而加快计算速度。
//     * 默认返回的是未排序的位置元素。通过 ASC 与 DESC 可让返回的位置元素以升序或者降序方式排列
//     *
//     * @param radius 半径（最大范围）
//     * @return
//     */
//    public static List<GeoRadiusResponse> geoRadius(String key, double longitude, double latitude, double radius, GeoUnit unit, GeoRadiusParam geoRadiusParam) {
//        Jedis jedis = null;
//        List<GeoRadiusResponse> result = null;
//        try {
//            jedis = getResource();
//            result = jedis.georadius(key, longitude, latitude, radius, unit, geoRadiusParam);
//        } catch (JedisException e) {
//            returnBrokenResource(jedis);
//            throw e;
//        } finally {
//            returnResource(jedis);
//        }
//        return result;
//    }
//
//    /**
//     * 根据给定的地理位置坐标（即经纬度）获取指定范围内的位置元素集合
//     * GEORADIUSBYMEMBER city guiyang 900 km WITHCOORD WITHDIST
//     *
//     * @param key
//     * @param radius         搜索半径
//     * @param unit           单位
//     * @param geoRadiusParam
//     * @return
//     */
//    public static List<GeoRadiusResponse> getRadiusByMember(String key, String city, double radius, GeoUnit unit, GeoRadiusParam geoRadiusParam) {
//        Jedis jedis = null;
//        List<GeoRadiusResponse> result = null;
//        try {
//            jedis = getResource();
//            result = jedis.georadiusByMember(key, city, radius, unit, geoRadiusParam);
//        } catch (JedisException e) {
//            returnBrokenResource(jedis);
//            throw e;
//        } finally {
//            returnResource(jedis);
//        }
//        return result;
//    }
//
//    /**
//     * 返回一个或多个位置元素的哈希字符串，该字符串具有唯一 ID 标识，它与给定的位置元素
//     * GEOHASH city lanzhou beijing shanghai
//     *
//     * @param key
//     * @param members
//     * @return
//     */
//    public static List<String> geoHash(String key, String... members) {
//        Jedis jedis = null;
//        List<String> result = null;
//        try {
//            jedis = getResource();
//            result = jedis.geohash(key, members);
//        } catch (JedisException e) {
//            returnBrokenResource(jedis);
//            throw e;
//        } finally {
//            returnResource(jedis);
//        }
//        return result;
//    }
//
//    /**
//     * 用于删除指定的地理位置元素
//     *
//     * @param key
//     * @param members
//     * @return
//     */
//    public static Long zRem(String key, String... members) {
//        Jedis jedis = null;
//        Long result = null;
//        try {
//            jedis = getResource();
//            result = jedis.zrem(key, members);
//        } catch (JedisException e) {
//            returnBrokenResource(jedis);
//            throw e;
//        } finally {
//            returnResource(jedis);
//        }
//        return result;
//    }

}
