package com.pcloud.common.utils.cache.redis;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import com.pcloud.common.utils.string.StringUtil;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

/**
 * 
 * @描述：redis集群初始化
 * @作者：songx
 * @创建时间：2017年9月13日,下午5:50:17
 * @版本：1.0
 */
@Configuration
@EnableCaching
@PropertySource(value = "classpath:redis.properties")
public class JedisClusterConfig {

	/**
	 * 
	 */
	private static final Logger LOGGER = LoggerFactory.getLogger(JedisClusterConfig.class);
	 
	@Value("${redis.cluster.host}")
	private String host;

	@Value("${redis.cluster.timeout}")
	private int timeout;
 
	@Value("${redis.cluster.maxRedirections}")
	private int maxRedirections;
 
	@Value("${redis.cluster.pool.maxTotal}")
	private int maxTotal;
 
	@Value("${redis.cluster.pool.minIdle}")
	private int minIdle;
 
	@Value("${redis.cluster.pool.maxIdle}")
	private int maxIdle;
 
	@Value("${redis.cluster.pool.maxWaitMillis}")
	private int maxWaitMillis;
	
	@Value("${redis.cluster.pool.timeBetweenEvictionRunsMillis}")
	private int timeBetweenEvictionRunsMillis;
 
	@Value("${redis.cluster.pool.testOnBorrow}")
	private boolean testOnBorrow;

	/**
	 * 正则校验IP
	 */
	private Pattern p = Pattern.compile("^.+[:]\\d{1,5}\\s*$");
	
	/**
	 * Jedis连接池
	 * 
	 * @return
	 */
	@Bean
	public GenericObjectPoolConfig jedisPoolConfig() {
		LOGGER.info("【redis】JedisPool注入成功,<START>");
		GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
		poolConfig.setMaxTotal(maxTotal);
		poolConfig.setMinIdle(minIdle);
		poolConfig.setMaxIdle(maxIdle);
		poolConfig.setMaxWaitMillis(maxWaitMillis);
		poolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
		poolConfig.setTestOnBorrow(testOnBorrow);
		return poolConfig;
	}
	
	/**
	 * JedisCluster
	 */
	@Bean
	public JedisCluster JedisClusterFactory() {
		LOGGER.info("【redis】JedisCluster创建,<START>");
		return new JedisCluster(parseHostAndPort(), timeout, maxRedirections, jedisPoolConfig());
	}

	/**
	 * 组装节点IP
	 * 
	 * @return
	 */
	private Set<HostAndPort> parseHostAndPort() {
		LOGGER.info("【redis】节点IP解析,<START>");
		Set<HostAndPort> hostAndPorts = new HashSet<HostAndPort>();
		if (StringUtil.isEmpty(host)) {
			throw new IllegalArgumentException("解析 jedis配置文件 -> 节点IP不能为空");
		}
		String[] hosts = host.split(",");
		for (int i = 0; i < hosts.length; i++) {
			String value = hosts[i];
			boolean isIpPort = p.matcher(value).matches();
			if (!isIpPort) {
				throw new IllegalArgumentException("解析 jedis配置文件 -> ip或 port不合法");
			}
			String[] ipAndPort = value.split(":");
			hostAndPorts.add(new HostAndPort(ipAndPort[0].trim(), Integer.parseInt(ipAndPort[1].trim())));
		}
		return hostAndPorts;
	}

}
