package org.springblade.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * 第一种分布式锁
 */
@Component
public class RedisTool {

    @Resource
    RedisTemplate redisTemplate;

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    // 获取锁之前的超时时间(获取锁的等待重试时间)
    private long acquireTimeout = 20000;
    // 获取锁之后的超时时间(防止死锁)
    private int timeOut = 60*10;

	/**
	 * 获取分布式锁
	 * @return 锁标识
	 */
	public boolean getRedisLockByScript(String lockName, String val) {
		String script = "if redis.call('setNx',KEYS[1],ARGV[1]) then if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('expire',KEYS[1],ARGV[2]) else return 0 end end";
		RedisScript<String> redisScript = new DefaultRedisScript<>(script, String.class);
		Object result = redisTemplate.execute(redisScript, Collections.singletonList(lockName),val,timeOut,TimeUnit.SECONDS);
		if("SUCCESS".equals(result)){
			return true;
		}else{
			log.info("lock err!");
		}
		return false;
	}

    /**
     * 获取分布式锁
     * @return 锁标识
     */
    public boolean getRedisLock(String lockName, String val) {
        Boolean b = redisTemplate.opsForValue().setIfAbsent(lockName, val, timeOut, TimeUnit.SECONDS);
        if(b){
            return true;
        }else{
            log.info("lock err!");
        }
        return false;
    }
    /**
     * 释放分布式锁
     * @param lockName 锁名称
     */
    public void unRedisLock(String lockName) {
        redisTemplate.delete(lockName);
        log.info("releaseLock success!");
    }
}
