package com.sundot.airport.exam.cache;

import cn.hutool.core.util.StrUtil;
import com.sundot.airport.common.core.redis.RedisCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * <b>功能名：ConcurrentLockHandler</b><br>
 * <b>说明：</b> 并发锁工具 <br>
 * <b>著作权：</b> Copyright (C) 2021 HUIFANEDU  CORPORATION<br>
 * <b>修改履历：</b><br>
 *
 * @author 2021-06-30 liangxiao
 */
@Component
public class ConcurrentLockHandler {
    /**
     * 锁key的前缀
     */
    private static final String LOCK_PREFIX = "conc:lock:";

    /**
     * 默认配置获取锁的过期时间（秒）
     */
    private static final long LOCK_TIMEOUT = 3L;

    private static final Logger log = LoggerFactory.getLogger(ConcurrentLockHandler.class);

    //    @Resource
//    private RedisCacheClient redisCacheClient;
    @Resource
    private RedisCache redisCache;

    /**
     * <b>方法名: </b> tryLock <br>
     * <b>说明: </b> 检查并尝试获取全局并发锁 <br>
     *
     * @param key   java.lang.String 键
     * @param value java.lang.String 值
     * @return boolean true获取成功，false获取失败<br>
     * <b>修改履历: </b>
     * @author 2021/6/30 liangxiao
     */
    public boolean tryLock(String key, String value) {
        return tryLock(key, value, LOCK_TIMEOUT);
    }

    /**
     * <b>方法名: </b> tryLock <br>
     * <b>说明: </b> 检查并尝试获取全局并发锁 <br>
     *
     * @param key     java.lang.String 键
     * @param value   java.lang.String 值
     * @param timeout long 超时时间。单位：秒。如果小于等于0则不会超时。
     * @return boolean true获取成功，false获取失败<br>
     * <b>修改履历: </b>
     * @author 2021/6/30 liangxiao
     */
    public boolean tryLock(String key, String value, long timeout) {
        log.info(String.format("tryLock:key=%s,value=%s,timeout=%d", key, value, timeout));
        if (timeout > 0) {
            return redisCache.setNX(LOCK_PREFIX + key, value, timeout);
        }
        return redisCache.setNX(LOCK_PREFIX + key, value);
    }

    /**
     * <b>方法名: </b> releaseLock <br>
     * <b>说明: </b> 主动释放锁 <br>
     *
     * @param key 锁的key值
     * @return void<br>
     * <b>修改履历: </b>
     * @author 2021/7/2 liangxiao
     */
    public void releaseLock(String key) {
        log.info(String.format("releaseLock:key=%s", key));
        if (StrUtil.isNotBlank(key)) {
            redisCache.deleteObject(LOCK_PREFIX + key);
        }
    }
}

