//package com.qmth.jkserver.common;
//
//import java.util.Collections;
//import java.util.Objects;
//import java.util.concurrent.TimeUnit;
//
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
////import org.springframework.data.redis.core.RedisCallback;
////import org.springframework.data.redis.core.RedisTemplate;
////import org.springframework.data.redis.core.script.DefaultRedisScript;
////import org.springframework.data.redis.core.script.RedisScript;
//import org.springframework.stereotype.Component;
//
///**
// * Redis分布式锁
// *
// * @author tianjun
// */
//@Component
//public class RedisLock {
//
//    private Logger logger = LoggerFactory.getLogger(RedisLock.class);
//
//    private static final String LOCK_PREFIX = "JK-SERVER-REDIS-LOCK-";
//
//    @Autowired
//    private RedisTemplate<String, Object> redisTemplate;
//
//    //加锁
//    private static final String LUA_SCRIPT_LOCK = "if redis.call('set',KEYS[1],ARGV[1],'NX','PX',ARGV[2]) then return '1' else return '0' end ";
//    private static RedisScript<String> scriptLock = new DefaultRedisScript<String>(LUA_SCRIPT_LOCK, String.class);
//
//    //解锁
//    private static final String LUA_SCRIPT_UNLOCK = "if redis.call('get', KEYS[1]) == ARGV[1] then return tostring(redis.call('del', KEYS[1])) else return '0' end";
//    private static RedisScript<String> scriptUnLock = new DefaultRedisScript<String>(LUA_SCRIPT_UNLOCK, String.class);
//
//    private static final String LOCK_SUCCESS = "1";
//    private static final String RELEASE_SUCCESS = "1";
//
//    /**
//     * 加锁
//     *
//     * @param key     缓存key
//     * @param value   缓存value
//     * @param timeout 缓存过期时间 单位毫秒
//     */
//    public boolean lock(String key, String value, int timeout) {
//        key = LOCK_PREFIX + key;
//        logger.info("======[key]:{},[value]:{},[timeout]:{}", key, value, timeout);
//        // 利用lambda表达式
////        String finalKey = key;
////		redisTemplate.expire(key,timeout,TimeUnit.MINUTES);
////        return (Boolean) redisTemplate.execute((RedisCallback) connection -> {
////            long expireAt = System.currentTimeMillis() + timeout + 1;
////            Boolean acquire = connection.setNX(finalKey.getBytes(), String.valueOf(expireAt).getBytes());
////            if (acquire) {
////                redisTemplate.expire(finalKey, timeout, TimeUnit.MINUTES);
////                return true;
////            } else {
////                byte[] value1 = connection.get(finalKey.getBytes());
////                if (Objects.nonNull(value1) && value1.length > 0) {
////                    long expireTime = Long.parseLong(new String(value1));
////                    // 如果锁已经过期
////                    if (expireTime < System.currentTimeMillis()) {
////                        // 重新加锁，防止死锁
////                        byte[] oldValue = connection.getSet(finalKey.getBytes(), String.valueOf(System.currentTimeMillis() + timeout + 1).getBytes());
////                        redisTemplate.expire(finalKey, timeout, TimeUnit.MINUTES);
////                        return Long.parseLong(new String(oldValue)) < System.currentTimeMillis();
////                    }
////                }
////            }
////            return false;
////        });
////    	执行拿锁的操作，注意这里，后面的三个参数分别对应了scriptLock字符串中的三个变量值，KEYS[1]，ARGV[1]，ARGV[2]，
////    	含义为锁的key，key对应的value，以及key 的存在时间(单位毫秒)
//    	Object result = redisTemplate.execute(scriptLock, redisTemplate.getStringSerializer(),
//    			redisTemplate.getStringSerializer(), Collections.singletonList(key), value,
//    	                        String.valueOf(timeout));
//    	logger.info("======[RedisLock] result:" + result);
//    	if (result != null && String.valueOf(result).equals(LOCK_SUCCESS)) {
//    		logger.info("======[RedisLock] key="+key+",value="+value+" locked succcess!");
//    		return true;
//    	}
//    	else {
//			return false;
//		}
//    }
//
//
//    /**
//     * 解锁
//     *
//     * @param key
//     * @param value
//     */
//    public boolean unlock(String key, String value) {
//        key = LOCK_PREFIX + key;
//        Object result = redisTemplate.execute(scriptUnLock, redisTemplate.getStringSerializer(),
//                redisTemplate.getStringSerializer(), Collections.singletonList(key), value);
//        logger.info("======[RedisUnLock] result:" + result);
//        if (result != null && String.valueOf(result).equals(RELEASE_SUCCESS)) {
//            logger.info("======[RedisUnLock] key=" + key + ",value=" + value + " Unlocked succcess!");
//            return true;
//        } else {
//            return false;
//        }
//    }
//
//}
