package cn.ezhizao.framework.lock;


import cn.ezhizao.common.utils.spring.SpringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import java.util.concurrent.TimeUnit;

/**
 * @author 韩方宇
 */
public class DistributionLock {

    private final RLock lock;

    public DistributionLock(String name) {
        RedissonClient client = SpringUtils.getBean(RedissonClient.class);
        this.lock = client.getLock(name);
    }

    public DistributionLock(String... names) {
        RedissonClient client = SpringUtils.getBean(RedissonClient.class);

        RLock[] lockList = new RLock[names.length];

        for (Integer i = 0; i < names.length; i++) {
            RLock rLock = client.getLock(names[i]);
            lockList[i] = rLock;
        }
        this.lock = client.getMultiLock(lockList);
    }

    public void lock(Runnable func) {
        this.lock();
        try {
            func.run();
        } catch (Exception e) {
            throw e;
        } finally {
            this.unlock();
        }
    }

    public void lock() {
        this.lock(5, 30, TimeUnit.SECONDS);
    }

    public void lock(long leaseTime, TimeUnit unit) {
        this.lock(-1, leaseTime, unit);
    }

    public void lock(long waitTime, long leaseTime, TimeUnit unit) {
        try {
            boolean result = this.lock.tryLock(waitTime, leaseTime, unit);
            if (!result) {
                throw new RuntimeException("加锁失败");
            }
        } catch (Exception e) {
            throw new RuntimeException("加锁失败");
        }
    }

    public void unlock() {
        this.lock.unlock();
    }
}
