/**
 * File Name：RedisCacheConfig.java
 *
 * Copyright Defonds Corporation 2015 
 * All Rights Reserved
 *
 */
package com.cftech.core.redis;

import com.cftech.core.util.DESUtil;
import com.cftech.core.util.SystemConfig;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Protocol;

import java.lang.reflect.Method;

 /**
 * @version
 * @EnableCaching 启用cache注解功能
 */
@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport{
    //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例，默认值也是8。
    private static int MAX_IDLE = 200;
    //等待可用连接的最大时间，单位毫秒，默认值为-1，表示永不超时。如果超过等待时间，则直接抛出JedisConnectionException；
    private static int MAX_WAIT = -1;

    private static String PASS= "";
    private static int port=6379;
    static
	{
		try {
			PASS = DESUtil.decrypt( SystemConfig.r.getProperty("spring.redis.password"),DESUtil.KEY);
			port=Integer.valueOf(SystemConfig.r.getProperty("spring.redis.port"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Bean
	public JedisPoolConfig getJedisPoolConfig()
	{
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxIdle(MAX_IDLE);
		config.setMaxWaitMillis(MAX_WAIT);
		config.setMaxTotal(150);
		return config;
	}

	@Bean
	public JedisPool jedisPool(JedisPoolConfig jedisPoolConfig)
	{
	 JedisPool jedisPool = new JedisPool(jedisPoolConfig, SystemConfig.r.getProperty("spring.redis.host"),port,
			 Protocol.DEFAULT_TIMEOUT, PASS);
	 return jedisPool;
	}

	@Bean
	public JedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig) {

		 JedisConnectionFactory factory = new JedisConnectionFactory();
	     //factory.setHostName("120.195.144.73");//汤沟正式
		factory.setHostName(SystemConfig.r.getProperty("spring.redis.host"));
		factory.setDatabase(Integer.parseInt(SystemConfig.r.getProperty("spring.redis.database")));
		//factory.setHostName("115.159.84.126");//畅服
		 //factory.setHostName("127.0.0.1");
	     factory.setPort(port);
	     factory.setUsePool(true);

	     factory.setPassword(PASS);
	     factory.setPoolConfig(jedisPoolConfig);
	     return factory;
//		 List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
//      	 JedisShardInfo shardMasterOne =  new JedisShardInfo("123.206.215.74", 6379,"主机器1");
//    	 shardMasterOne.setPassword(PASS);
//    	 shards.add(shardMasterOne);
//    	 
//    	 JedisShardInfo shardMasterSecond =  new JedisShardInfo("115.159.84.126", 6379,"主机器2");
//    	 shardMasterSecond.setPassword(PASS);
//    	 shards.add(shardMasterSecond);
//    	 JedisPoolConfig config = new JedisPoolConfig();
//         config.setMaxIdle(MAX_IDLE);
//         config.setMaxWaitMillis(MAX_WAIT);
//         config.setMaxTotal(20);
//         Set<String> set =new HashSet<String>();
//         set.add("192.168.220.129:26379");
//         set.add("192.168.220.129:26378");
//    	 RedisSentinelConfiguration rsc = new RedisSentinelConfiguration("mymaster",set);//哨兵模式 ,测试环境用分布式 
//		return new JedisConnectionFactory(shardMasterOne);
	}

	@Bean
	public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
		RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
		redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
		redisTemplate.setConnectionFactory(cf);
		return redisTemplate;
	}

	@Bean
	public CacheManager cacheManager(RedisTemplate redisTemplate) {
		
		RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
		
		// Number of seconds before expiration. Defaults to unlimited (0)
		cacheManager.setDefaultExpiration(3600*24);//3000); // Sets the default expire time (in seconds)默认一天时间
		
//		Map<String,Long> expires = new HashMap<String, Long>();//自定义Redis缓存的自定义过期时间
//		expires.put("AccountCache",1000L);
//		cacheManager.setExpires(expires);
		return cacheManager;
	}
	
	
	
	@Override
	public KeyGenerator keyGenerator() {	return new KeyGenerator() {
		@Override
		public Object generate(Object o, Method method, Object... objects) {
			StringBuilder sb = new StringBuilder();
			sb.append(o.getClass().getName());
			sb.append(method.getName());
			for (Object obj : objects) {
				sb.append(obj.toString());
			} 
			return sb.toString();
		}
	};}

	
	
//	@Bean
//	public KeyGenerator customKeyGenerator() {
//		return new KeyGenerator() {
//			@Override
//			public Object generate(Object o, Method method, Object... objects) {
//				StringBuilder sb = new StringBuilder();
//				sb.append(o.getClass().getName());
//				sb.append(method.getName());
//				for (Object obj : objects) {
//					sb.append(obj.toString());
//				}
//				return sb.toString();
//			}
//		};
//	}
}
