package cn.com.ty.lift.ud.redis;

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

import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import cn.com.ty.lift.ud.neety.protocol.GsonTypeAdapter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class RedisUtil {
    /**
     * 是否开启redis缓存 true开启 false关闭
     */
    @Value("${spring.redis.open}")
    private boolean open;

    @Value("${spring.redis.db}")
    private Integer db;

    @Value("${spring.redis.timeout}")
    private Integer timeout;

    @Autowired(required = false)
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired(required = false)
    private ValueOperations<String, String> valueOperations;
    @Autowired(required = false)
    private HashOperations<String, String, Object> hashOperations;
    @Autowired(required = false)
    private ListOperations<String, Object> listOperations;
    @Autowired(required = false)
    private SetOperations<String, Object> setOperations;
    @Autowired(required = false)
    private ZSetOperations<String, Object> zSetOperations;

    /**
     * 默认过期时长，单位：秒
     */
    public final static long DEFAULT_EXPIRE = 7200;

    /* public RedisUtil(){
        RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
        DefaultStringRedisConnection stringRedisConnection = new DefaultStringRedisConnection(redisConnection);
        stringRedisConnection.select(db);
    }*/

    public RedisUtil() {
        log.info("RedisUtil init");
    }

    /**
     * 不设置过期时长
     */
    public final static long NOT_EXPIRE = -1;
    public final static JSONObject json = new JSONObject();
//    public final static Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls().disableHtmlEscaping().create();

    public boolean exists(String key) {
        if (!open) {
            return false;
        }

        return redisTemplate.hasKey(key);
    }

    /**
     *  根据模板查询，redis中符合的key列表
     * @param pattern
     * @return
     */
    public Set<String> keys(String pattern){
        Set<String> keys = redisTemplate.keys(pattern);
        return keys;
    }

    public void setList(String key, Object value, long expire) {
        if (!open) {
            return;
        }
        try {
            valueOperations.set(key, toJson(value));

        } catch (Exception e0) {
            System.out.println(e0.getMessage());
        }
        if (expire != NOT_EXPIRE) {
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
    }

    public void setValue(String key, Object value) {
        if (!open) {
            return;
        }
        try {

            valueOperations.set(key, toJson(value));

        } catch (Exception e0) {
            System.out.println(e0.getMessage());
        }
    }

    public <T> T get(String key, Class<T> clazz, long expire) {
        if (!open) {
            return null;
        }

        String value = valueOperations.get(key);
        if (expire != NOT_EXPIRE) {
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
        return value == null ? null : fromJson(value, clazz);
    }

    public <T> T get(String key, Class<T> clazz) {
        if (!open) {
            return null;
        }

        return get(key, clazz, NOT_EXPIRE);
    }

    public String getValue(String key, long expire) {
        if (!open) {
            return null;
        }

        String value = valueOperations.get(key);
        if (expire != NOT_EXPIRE) {
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
        return value;
    }

    public String getValue(String key) {
        if (!open) {
            return null;
        }

        return getValue(key, NOT_EXPIRE);
    }

    public void delete(String key) {
        if (!open) {
            return;
        }

        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }

    public void delete(String... keys) {
        if (!open) {
            return;
        }

        for (String key : keys) {
            redisTemplate.delete(key);
        }
    }

    public void delete(List<String> keys) {
        if (!open) {
            return;
        }

        for (String key : keys) {
            redisTemplate.delete(key);
        }
    }

    public void deletePattern(String pattern) {
        if (!open) {
            return;
        }

        Set<String> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0) {
            redisTemplate.delete(keys);
        }
    }

    /**
     * Object转成JSON数据
     */
    private String toJson(Object object) {
        if (!open) {
            return null;
        }

        if (object instanceof Integer || object instanceof Long || object instanceof Float || object instanceof Double
            || object instanceof Boolean || object instanceof String) {
            return String.valueOf(object);
        }

        return JSONObject.toJSONString(object);
    }

    /**
     * JSON数据，转成Object
     */
    private <T> T fromJson(String json, Class<T> clazz) {
        if (!open) {
            return null;
        }
//        return GsonTypeAdapter.getGson().fromJson(json, clazz);
        // return gson.fromJson(json, clazz);
        return JSONObject.parseObject(json, clazz);
    }

    public <T> T getKey(String key, Class<T> clazz) {
        String value = valueOperations.get(key);
//        return value == null ? null : GsonTypeAdapter.getGson().fromJson(value, clazz);
        return value == null ? null : JSONObject.parseObject(value, clazz);
    }

    public String getKey(String key) {
        String value = valueOperations.get(key);
        return value == null ? null : value;
    }

}
