package com.reyun.saas.common.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class RedisUtils {

	@Resource
	private StringRedisTemplate redisTemplate;


	/**
	 * 根据key获取hash数据
	 * @param key key
	 * @return map
	 */
	public Map<String, String> hgetAll(String key) {

		Map<String,String> result = new HashMap<>();
		HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();
		result = hashOperations.entries(key);
		return result;
	}

	/**
	 * 存入map
	 * @param key 键
	 * @param map map
	 */
	public boolean hsetAll(String key, Map<String, String> map) {
		try {
			redisTemplate.opsForHash().putAll(key,map);
			return true;
		} catch (Exception exception) {
			log.error("redisUtils.delete()发生异常!",exception);
			return false;
		}
	}


	/**
	 * 获取键
	 * @param key 键
	 * @return list<String>集合
	 */
	public List<String> getList(String key){
		try {
			return redisTemplate.opsForList().range(key, 0, -1);
		} catch (Exception exception) {
			log.error("redisUtils.delete()发生异常!",exception);
			return null;
		}
	}


	/**
	 * 删除元素
	 * @param key 键
	 */
	public boolean delete(String key) {
		try {
			redisTemplate.delete(key);
			return true;
		} catch (Exception exception) {
			log.error("redisUtils.delete()发生异常!",exception);
			return false;
		}
	}

	/**
	 * 获取元素
	 * @param key 键
	 * @return 值
	 */
	public String get(String key) {
	    return redisTemplate.opsForValue().get(key);
	}

	/**
	 * 保存元素(无过期时间)
	 * @param key 键
	 * @param value 值
	 */
	public boolean set(String key,String value){
		try {
			redisTemplate.opsForValue().set(key,value);
			return true;
		} catch (Exception exception) {
			log.error("redisUtils.delete()发生异常!",exception);
			return false;
		}
	}


	/**
	 * 获取元素的超时时间
	 * @param key 键
	 * @return 超时时间
	 */
	public Long getExpireTime(String key) {
		return redisTemplate.getExpire(key);
	}


	/**
	 * 自送释放的锁
	 * 适用于多服务下 cron表达式的定时任务
	 * @param key 锁名称
	 * @param expireTime 锁释放时间  默认时间单位是秒
	 * @return 是否加锁成功
	 */
	public boolean tryLock(String key, int expireTime) {
		if(key == null || "".equals(key)){
			return false;
		}
		try {
			return redisTemplate.opsForValue().setIfAbsent(key, "lock", expireTime, TimeUnit.SECONDS);
		} catch (Exception exception) {
			log.error("RedisUtils.tryLock()方法发生异常",exception);
			return false;
		}
	}


	/**
	 * 保存元素并指定超时时间
	 * @param key 键
	 * @param value 值
	 * @param expireTime 超时时间
	 * @param timeUnit 超市时间 时间单位
	 * @return 是否成功
	 */
	public boolean expireValue(String key, String value, int expireTime,TimeUnit timeUnit) {
		try {
			redisTemplate.opsForValue().set(key,value,expireTime,timeUnit);
			return true;
		} catch (Exception exception) {
			log.error("redisUtils.expireValue()发生异常!",exception);
			return false;
		}
	}


	/**
	 * 上锁
	 * @param key 锁名
	 * @param timeOut 非手动释放超时时间
	 * @param timeUnit 超时时间单位
	 * @return 是否加锁成功
	 */
	public boolean lokc(String key,Long timeOut,TimeUnit timeUnit){
		try {
			return redisTemplate.opsForValue().setIfAbsent(key, "lock", timeOut, TimeUnit.SECONDS);
		} catch (Exception exception) {
			log.error("redisUtils.lokc()发生异常!",exception);
			return false;
		}
	}


	/**
	 * 释放锁
	 * @param key 要释放的锁
	 * @return 是否成功
	 */
	public boolean unlock(String key){
		try {
			return redisTemplate.delete(key);
		} catch (Exception exception) {
			log.error("redisUtils.unlock()发生异常!",exception);
			return false;
		}
	}

}
