package com.sy.coinage.config;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson2.JSON;
import com.sy.coinage.core.redis.RedisPublisherService;
import com.sy.coinage.core.redis.RedisService;

/**
 * -Redis配置
 */
@Configuration
public class RedisServiceConfig {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Bean
    public RedisService redisService() {
        return new RedisService() {
            @Override
            public boolean set(String key, String value) {
                try {
                    redisTemplate.opsForValue().set(key, value);
                    return true;
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }

            @Override
            public boolean setObject(String key, Object value) {
                try {
                    redisTemplate.opsForValue().set(key, value);
                    return true;
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }

            @Override
            public boolean setList(String key, List<Object> value) {
                try {
                    redisTemplate.opsForList().rightPushAll(key, value);
                    return true;
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }

            @Override
            public boolean expire(String key, long expire) {
                return redisTemplate.expire(key, expire, TimeUnit.SECONDS);
            }

            @Override
            public String get(String key) {
                return key == null ? null : (String) redisTemplate.opsForValue().get(key);
            }

            @Override
            public Object getObject(String key) {
                Object obj = redisTemplate.opsForValue().get(key);
                return obj;
            }

            @Override
            public List<Object> getList(String key, long start, long end) {
                try {
                    return redisTemplate.opsForList().range(key, start, end);
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }

            @Override
            @SuppressWarnings("all")
            public void del(String... key) {
                if (key != null && key.length > 0) {
                    if (key.length == 1) {
                        redisTemplate.delete(key[0]);
                    } else {
                        redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
                    }
                }
            }

            @Override
            public long incr(String key, long time) {
                long value = redisTemplate.opsForValue().increment(key, 1);
                if (time > 0) {
                    redisTemplate.expire(key, time, TimeUnit.SECONDS);
                }
                return value;
            }

            @Override
            public long decr(String key, long time) {
                long value = redisTemplate.opsForValue().increment(key, -1);
                if (time > 0) {
                    redisTemplate.expire(key, time, TimeUnit.SECONDS);
                }
                return value;
            }

            @Override
            public Map<Object, Object> getMap(String key) {
                try {
                    return redisTemplate.opsForHash().entries(key);
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }

            @Override
            public Boolean hasKey(String key) {
                return redisTemplate.hasKey(key);
            }

            @Override
            public boolean addSet(String setName, List<Object> list) {
                try {
                    for (Object obj : list) {
                        redisTemplate.opsForSet().add(setName, obj);
                    }
                    return true;
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }

            @Override
            public Set<Object> membersForSet(String setName) {
                return redisTemplate.opsForSet().members(setName);
            }

            @Override
            public Boolean isMember(String setName, Object item) {
                return redisTemplate.opsForSet().isMember(setName, item);
            }

            @Override
            public void updateSet(String setName, List<Object> list) {
                this.del(setName);
                try {
                    for (Object obj : list) {
                        redisTemplate.opsForSet().add(setName, obj);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void update(String key, String value) {
                this.del(key);
                this.set(key, value);
            }

            @Override
            public boolean setIfAbsent(String key, String value, Long time) {
                try {
                    return redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS);
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }

            @Override
            public void releaseLock(String key, String value) {
                String cacheValue = get(key);
                if (cacheValue != null && value != null && value.equals(cacheValue)) {
                    del(key);
                }
            }

            @Override
            public boolean hmset(String key, Map<Object, Object> map) {
                try {
                    redisTemplate.opsForHash().putAll(key, map);
                    return true;
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }

            @Override
            public Collection<String> keys(String pattern) {
                return redisTemplate.keys(pattern);
            }

            @Override
            public Long delKeys(String pattern) {
                Collection<String> keys = redisTemplate.keys(pattern);
                return redisTemplate.delete(keys);
            }

        };
    }

    @Bean
    public RedisPublisherService sendMessageService() {
        return new RedisPublisherService() {
            @Override
            public String sendMsg(String topic, Object msg) {
                try {
                    redisTemplate.convertAndSend(topic, JSON.toJSONString(msg));
                    return "消息发送成功";
                } catch (Exception e) {
                    e.printStackTrace();
                    return "消息发送失败";
                }
            }
        };
    }

}
