package cn.com.countrygarden.bi.main.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smartframework.common.GlobalConfig;
import org.smartframework.common.utils.ExStringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Redis工具类
 * 
 * @author huangzhengjun
 *
 */
public class RedisUtils {

	protected static final Logger log = LoggerFactory.getLogger(RedisUtils.class);

	private static String redisServer;

	private static String redisPort;

	private static String redisPassword;

	private static JedisPool jedisPool;

	static {

		if (redisServer == null) {
			redisServer = GlobalConfig.getConfigValue("redis.server");
			redisPort = GlobalConfig.getConfigValue("redis.port");
			redisPassword = GlobalConfig.getConfigValue("redis.password");
		}

		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(10);
		config.setMaxIdle(2);
		config.setMaxWaitMillis(10000L);
		config.setTestOnBorrow(true);
		int port = ExStringUtils.parseInt(redisPort, 6379);
		jedisPool = new JedisPool(config, redisServer, port, 10000, redisPassword);
	}

	public static Jedis getClicent() {
		Jedis jedisClient = jedisPool.getResource();
		return jedisClient;
	}

	@SuppressWarnings("deprecation")
	public static void returnResource(Jedis jedis) {
		// jedis.close();
		jedisPool.returnResource(jedis);
	}

	public static void put(String key, String value, int seconds) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			jedis.set(key, value);
			jedis.expire(key, seconds);

		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}

	}

	public static void put(String key, String value) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			jedis.set(key, value);

		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}

	}

	public static long hdel(String key, String... fields) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			long value = jedis.hdel(key, fields);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return -1;
	}

	public static String hget(String key, String field) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			String value = jedis.hget(key, field);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return null;
	}

	public static Long hlen(String key) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			Long value = jedis.hlen(key);

			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return new Long(-1);
	}

	public static Set<String> hkeys(String key) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			Set<String> value = jedis.hkeys(key);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return null;
	}

	public static Map hgetAll(String key) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			Map value = jedis.hgetAll(key);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return null;
	}

	public static long hset(String key, String field, String value) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			long result = jedis.hset(key, field, value);
			return result;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}

		return -1;
	}

	public static String hmset(String key, Map hash) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			String value = jedis.hmset(key, hash);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}

		return null;
	}

	public static String testCmd(String key) {

		try {
			long t1 = System.currentTimeMillis();
			Jedis jedis = getClicent();
			log.info("time1=" + (System.currentTimeMillis() - t1));
			t1 = System.currentTimeMillis();
			String value = jedis.get(key);

			log.info("time2=" + (System.currentTimeMillis() - t1));
			t1 = System.currentTimeMillis();

			for (int i = 0; i < 10; i++) {
				put(key, 100);
			}
			log.info("time21=" + (System.currentTimeMillis() - t1));
			t1 = System.currentTimeMillis();

			for (int i = 0; i < 10; i++) {
				put(key, 100);
				get(key);
			}
			log.info("time22=" + (System.currentTimeMillis() - t1));
			t1 = System.currentTimeMillis();

			returnResource(jedis);
			log.info("time3=" + (System.currentTimeMillis() - t1));

			return value;

		} catch (Exception ex) {
			log.error("{}", ex);
		}

		return null;

	}

	public static String get(String key) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			String value = jedis.get(key);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}

		return null;

	}

	/**
	 * 
	 * @param key
	 * @param seconds
	 * @return
	 */
	public static Long expire(String key, int seconds) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			Long value = jedis.expire(key, seconds);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}

		return new Long(-1);

	}

	public static void delete(String key){
		Jedis jedis = null;
		try{
			jedis = getClicent();
			jedis.del(key);
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}

	}

	/**
	 * 
	 * @param key
	 * @param unixTime
	 * @return
	 */
	public static Long expireAt(String key, int unixTime) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			Long value = jedis.expireAt(key, unixTime);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}

		return new Long(-1);
	}

	public static Long getDbSize() {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			Long dbSize = jedis.dbSize();
			return dbSize;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}

		return new Long(-1);

	}

	public static Set getKeys(String pattern) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			Set keys = jedis.keys(pattern);
			return keys;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return new HashSet();
	}

	public static void put(String key, int value, int seconds) {
		put(key, String.valueOf(value), seconds);
	}

	public static void put(String key, int value) {
		put(key, String.valueOf(value));
	}

	public static int getInt(String key) {
		try {
			String value = get(key);
			return Integer.parseInt(value);
		} catch (Exception ex) {
			return 0;
		}
	}

	public static void putMap(String key, Map map, int seconds) {
		put(key, JSON.toJSONString(map), seconds);
	}

	public static void putMap(String key, Map map) {
		put(key, JSON.toJSONString(map));
	}

	public static Map getMap(String key) {
		String jsonStr = get(key);
		if (jsonStr != null) {
			JSONObject tmpJson = JSON.parseObject(jsonStr);
			return JSON.toJavaObject(tmpJson, Map.class);
		}
		return null;
	}

	public static void put(String key, long value, int seconds) {
		put(key, String.valueOf(value), seconds);
	}

	public static void put(String key, long value) {
		put(key, String.valueOf(value));
	}

	public static long getLong(String key) {

		try {
			String value = get(key);
			return Long.parseLong(value);
		} catch (Exception ex) {
			return 0;
		}
	}

	public static void incr(String key) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			jedis.incr(key);
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
	}

	public static long lpush(String key, String message) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			long size = jedis.lpush(key, message);
			return size;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return 0;

	}

	public static String lpop(String key) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			String value = jedis.rpop(key);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return null;
	}

	public static long rpush(String key, String message) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			long size = jedis.lpush(key, message);
			return size;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return 0;
	}

	public static String rpop(String key) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			String value = jedis.rpop(key);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return null;
	}

	public static String ltrim(String key, long start, long end) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			String result = jedis.ltrim(key, start, end);
			return result;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return null;

	}

	public static List lrange(String key, long start, long end) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			List resultList = jedis.lrange(key, start, end);
			return resultList;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return null;
	}

	public static List<String> brpop(String key, int timeout) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			List<String> resultList = jedis.brpop(timeout, key);
			return resultList;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return null;

	}

	public static void publishMessage(String channel, String message) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			jedis.publish(channel, message);
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
	}

	public static void closeMessageChannel(String channel) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			jedis.publish(channel, "quit");
			jedis.del(channel);
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}

	}

	public static boolean isRunning() {
		Jedis jedis=null;
		boolean result = false;
		try {
			jedis = getClicent();
			String value = String.valueOf(System.currentTimeMillis());
			jedis.set("time", value);
			if (value.equalsIgnoreCase(jedis.get("time"))) {
				result = true;
			}

		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
			result = false;
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}

		return result;
	}

	public static long llen(String key) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			long length = jedis.llen(key);
			return length;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return 0;

	}

	public static long del(String key) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			long length = jedis.del(key);
			return length;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return 0;
	}

	public static long getNumActive() {
		return jedisPool.getNumActive();
	}

	public static double zincrby(String key, String member, double score) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			double value = jedis.zincrby(key, score, member);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return 0;

	}

	public static double zadd(String key, String member, double score) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			double value = jedis.zadd(key, score, member);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return 0;
	}

	public static double zscore(String key, String member) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			double value = jedis.zscore(key, member);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return 0;

	}

	public static Set zrange(String key, long start, long end) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			Set value = jedis.zrange(key, start, end);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return null;
	}

	public static Set zrangeWithScores(String key, long start, long end) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			Set value = jedis.zrangeWithScores(key, start, end);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return null;

	}

	public static Set zrangeByScore(String key, double min, double max) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			Set value = jedis.zrangeByScore(key, min, max);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return null;
	}

	public static long zcount(String key, double min, double max) {
		Jedis jedis = null;
		try{
			jedis = getClicent();
			long value = jedis.zcount(key, min, max);
			return value;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return 0;

	}
	
	public static long sadd(String key, String value){
		Jedis jedis = null;
		try{
			jedis = getClicent();
			long result = jedis.sadd(key, value);
			return result;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return 0;
	}
	
	public static boolean sismember(String key , String value){
		Jedis jedis = null;
		try{
			jedis = getClicent();
			boolean result = jedis.sismember(key,value);
			return result;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return false;
	}
	
	public static boolean exits(String key){
		Jedis jedis = null;
		try{
			jedis = getClicent();
			boolean result = jedis.exists(key);
			return result;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return false;
	}

	public static boolean hexits(String key,String field){
		Jedis jedis = null;
		try{
			jedis = getClicent();
			boolean result = jedis.hexists(key,field);
			return result;
		} catch(Exception ex){
			log.error("RedisUtils",ex);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return false;
	}
	
	public static void main(String[] args) {

		long t1 = System.currentTimeMillis();

		Jedis jedis = RedisUtils.getClicent();
		for (int i = 0; i < 100000; i++) {
			// jedis.hset("CarCount2", "test", "1");
			jedis.zincrby("CarCount3", 1, "test");
		}

		returnResource(jedis);

		System.out.println("time=" + (System.currentTimeMillis() - t1));
	}
}
