package com.brilliance.isc.common.lock.impl;

import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import com.brilliance.isc.common.lock.LockInfo;
import com.brilliance.isc.common.util.StringUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

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

/**
 * 基于Redis实现的
 */

@Component
public class RedisBizLocker extends AbstractBizLocker {

    private final Logger logger = LoggerFactory.getLogger(RedisBizLocker.class);

    @Resource
    private RedissonClient redissonClient;

    private boolean switchFlag = true;

    /**
     * @param key 为业务主键，使用LockInfo的方法生成key
     * @param value 为业务锁定信息，一般为交易码+操作人，使用LockInfo的方法生成value
     * @param seconds 锁定时间
     * @return
     */
    @Override
    public boolean lock(String key,String value, long seconds) {
        if(!switchFlag){
            logger.info("锁定函数暂时关闭");
            return true;
        }
        boolean isSuccess = false;
        RBucket<String> bucket = redissonClient.getBucket(key);
        String oldValue = bucket.get();
        // 不存在时，新增
        if (StringUtils.isEmpty(oldValue)) {
            isSuccess = bucket.trySet(value,seconds, TimeUnit.SECONDS);
            logger.info("锁key:{},value:{}，结果:{}",key,value,isSuccess);
            return isSuccess;
        }
        // 相同时，刷新时间
        if (oldValue.equals(value)) {
            if(value.endsWith("#true")) {
                isSuccess = bucket.setIfExists(value, seconds, TimeUnit.SECONDS);
                logger.info("锁已重入并刷新时间key:{},value:{}",key,value);
            }else{
                logger.info("锁无法重入key:{},value:{}",key,value);
            }
        }
        return isSuccess;
    }

    @Override
    public LockInfo getLock(LockInfo lockInfo) {
        if(!switchFlag){
            logger.info("锁定函数暂时关闭");
            return null;
        }
        String key = lockInfo.genLockKey();
        RBucket<String> bucket = redissonClient.getBucket(key);
        String value = bucket.get();
        logger.info("返回锁信息key:{},value:{}",key,value);
        if(value != null){
            return new LockInfo(key,value);
        }
        return null;
    }


    @Override
    public boolean unlock(LockInfo lockInfo) {
        if(!switchFlag){
            logger.info("锁定函数暂时关闭");
            return true;
        }
        String key = lockInfo.genLockKey();
        RBucket<String> bucket = redissonClient.getBucket(key);
        String value = bucket.get();
        logger.info("返回锁信息key:{},value:{}",key,value);
        if(value != null){
            LockInfo oldLockInfo = new LockInfo(key,value);
            if(oldLockInfo.getUsrId().equals(lockInfo.getUsrId())){
                logger.info("删除锁{}",key);
                bucket.delete();
                return true;
            }else{
                logger.info("{}锁定人不一致，不允许删除,oldUserId:{},curUserId{},",key,oldLockInfo.getUsrId(),lockInfo.getUsrId());
            }
        }

        return false;
    }

    public boolean lockForce(String key,String value, long seconds) {
        logger.info("强制占用锁{}:{}",key,value);
        RBucket<String> bucket = redissonClient.getBucket(key);
        bucket.set(value,seconds,TimeUnit.SECONDS);
        return true;
    }



    /**
     * 强制解锁
     *
     * @param lockInfo
     * @return
     */
    @Override
    public boolean unlockForce(LockInfo lockInfo) {
        String key = lockInfo.genLockKey();
        logger.info("强制删除锁{}",key);
        RBucket<String> bucket = redissonClient.getBucket(key);
        return bucket.delete();
    }

    /**
     * 删除当前交易相关锁信息
     *
     * @param transName
     * @param userId
     */
    @Override
    public boolean unlockAllOfTrans(String transName, String userId) {
        return false;
    }
}
