package com.freemud.sdk.api.assortment.order.util;

import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

/**
 * @author haibo.jiang
 * @Description:
 * @date 2019/11/6 14:38
 */
public class LockUtils {

    private static String redis_lock_after="saas:lockAfter:";

    public static Boolean lockAfter(RedisTemplate redisTemplate,String afterId){
        return redisLock(redisTemplate,redis_lock_after+afterId);
    }

    public static Boolean lock(RedisTemplate redisTemplate,String key,Long second){
        return redisLockByTime(redisTemplate,key,second);
    }

    private static boolean redisLock(RedisTemplate redisTemplate,String key){
        String lock =  key;
        // 利用lambda表达式
        return (Boolean) redisTemplate.execute((RedisCallback) connection -> {
            long expireAt = 300;
            Boolean acquire = connection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes());

            if (acquire) {
                connection.expire(lock.getBytes(),expireAt);
                return true;
            } else {
                return false;
            }
        });
    }

    private static boolean redisLockByTime(RedisTemplate redisTemplate,String key,Long second){
        String lock =  key;
        Long lockSecond = second;
        // 利用lambda表达式
        return (Boolean) redisTemplate.execute((RedisCallback) connection -> {
            long expireAt = second;
            Boolean acquire = connection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes());

            if (acquire) {
                connection.expire(lock.getBytes(),expireAt);
                return true;
            } else {
                return false;
            }
        });
    }

    /**
     * 解锁 无论是否加锁成功，都需要调用unlock 应该以： lock(); try { doSomething(); } finally {
     * unlock()； } 的方式调用
     */
    public static void unlock(RedisTemplate redisTemplate,String lockKey) {
        redisTemplate.delete(lockKey);
    }

}
