package com.qs.mp.framework.redis;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

@Component
public class RedisUtil {

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

	@Resource(name = "redisTemplate")
	private RedisTemplate<String, Object> redisObjectTemplate;

	@Resource(name = "stringRedisTemplate")
	private RedisTemplate<String, String> redisStringTemplate;
	
	private static long expireTime = 1000*60*60*24; //24小时过期；
	
	private static long expireTime48 = 1000*60*60*24*24; //24小时过期；
	/**
	 * 批量删除对应的value
	 * 
	 * @param keys
	 */
	public void remove(final String... keys) {
		for (String key : keys) {
			remove(key);
		}
	}

	/**
	 * 批量删除key
	 * 
	 * @param pattern
	 */
	public void removePattern(final String pattern) {
		Set<String> keys = redisStringTemplate.keys(pattern);
		logger.info("keys size:"+keys.size());
		if (keys.size() > 0)
			redisStringTemplate.delete(keys);
	}

	/**
	 * 批量查询key
	 * @param pattern
	 * @return
	 */
	public Set<String> getKeys(final String pattern){
	    return redisStringTemplate.keys(pattern);
	}
	/**
	 * 删除对应的value
	 * 
	 * @param key
	 */
	public void remove(final String key) {
		if (exists(key)) {
			redisStringTemplate.delete(key);
		}
	}

	/**
	 * 判断缓存中是否有对应的value
	 * 
	 * @param key
	 * @return
	 */
	public boolean exists(final String key) {
		return redisStringTemplate.hasKey(key);
	}

	/**
	 * 读取缓存
	 * 
	 * @param key
	 * @return
	 */
	public String get(final String key) {
		Object result = null;
		redisStringTemplate.setValueSerializer(new StringRedisSerializer());
		ValueOperations<String, String> operations = redisStringTemplate.opsForValue();
		result = operations.get(key);
		if (result == null) {
			return null;
		}
		return result.toString();
	}

	/**
	 * 写入缓存,key默认过期时间为24小时
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean set(final String key, String value) {
		boolean result = false;
		try {
			ValueOperations<String, String> operations = redisStringTemplate.opsForValue();
			operations.set(key, value);
			redisStringTemplate.expire(key, expireTime, TimeUnit.SECONDS);
			result = true;
		} catch (Exception e) {
			logger.info("set data error.", e);
		}
		return result;
	}
	
	public boolean set(final String key, Object value) {
		try {
			ValueOperations<String, Object> operations = redisObjectTemplate.opsForValue();
			operations.set(key, value);
			return true;
		} catch (Exception e) {
			logger.info("set data error.", e);
		}
		return false;
	}
	
	public Object getObject(final String key) {
		Object result = null;
		ValueOperations<String, Object> operations = redisObjectTemplate.opsForValue();
		result = operations.get(key);
		if (result == null) {
			return null;
		}
		return result;
	}
	
	public boolean setWithExpire24H(final String key, String value) {
		return set(key,value,expireTime);
	}
	
	public boolean setWithExpire48H(final String key, String value) {
        return set(key,value,expireTime48);
    }

	/**
	 * 写入缓存，指定过期时间
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean set(final String key, String value, Long expireTime) {
		boolean result = false;
		try {
			ValueOperations<String, String> operations = redisStringTemplate.opsForValue();
			operations.set(key, value);
			redisStringTemplate.expire(key, expireTime, TimeUnit.SECONDS);
			result = true;
		} catch (Exception e) {
			logger.info("set data error.", e);
		}
		return result;
	}

	public boolean hmset(String key, Map<String, String> value) {
		boolean result = false;
		try {
			redisStringTemplate.opsForHash().putAll(key, value);
			result = true;
		} catch (Exception e) {
			logger.info("hmset data error.", e);
		}
		return result;
	}

	public Map<Object, Object> hmget(String key) {
		Map<Object, Object> result = null;
		try {
			result = redisStringTemplate.opsForHash().entries(key);
		} catch (Exception e) {
			logger.info("hmset data error.", e);
		}
		return result;
	}

	public boolean zsetPut(final String key, String value, double score) {
		boolean result = false;
		try {
			ZSetOperations<String, String> operations = redisStringTemplate.opsForZSet();
			result = operations.add(key, value, score);
		} catch (Exception e) {
			logger.info("zset data error.", e);
		}
		return result;
	}

	/**
	 * 从key列表左边（从头部）插入 值
	 *
	 * @param key   不能为空
	 * @param value 插入列表的值
	 * @return 返回列表插入后的长度
	 */
	public Long leftPush(String key, String value) {
		long result = 0;
		try {
			ListOperations<String, String> operations = redisStringTemplate.opsForList();
			result = operations.leftPush(key, value);
		} catch (Exception e) {
			logger.info("list data error.", e);
		}
		return result;
	}
	
	
	/**
	 * @param key
	 * @return 从队列中移除一个元素
	 */
	public String rightPop(String key) {
		try {
			ListOperations<String, String> operations = redisStringTemplate.opsForList();
			if(operations.size(key) >0) {
				return operations.rightPop(key);
			}
		} catch (Exception e) {
			logger.info("rightPop data error.", e);
		}
		return null;
	}
	
	/**
	 * @param key
	 * @param value
	 * @param timeout 单位s
	 * 
	 * @return
	 */
	public boolean setLockKey(final String key, String value,long timeout) {
        boolean result = false;
        try {
            ValueOperations<String, String> operations = redisStringTemplate.opsForValue();
	            result = operations.setIfAbsent(key, value, timeout, TimeUnit.SECONDS);
        } catch (Exception e) {
        	logger.info("set scheduler error.", e);
        }
        return result;
    }
}
