package com.mortals.xhx.tools.lock.service.impl;

import com.mortals.framework.service.ICacheService;
import com.mortals.xhx.common.keys.RedisCacheKeys;
import com.mortals.xhx.tools.lock.service.ILockService;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

/**
 * redis 实现分布式锁机制
 * @author zxfei
 */
@CommonsLog
@Service("redisLockService")
//@ConditionalOnProperty("application.cache.redis")
public class RedisLockServiceImpl implements ILockService {
    private static ThreadLocal<String> threadLocal = new ThreadLocal<>();

    @Autowired
    private ICacheService cacheService;

    @Override
    public boolean lock(String lockKey) {
        return lock(lockKey, null);
    }

    @Override
    public boolean lock(String lockKey, Long unlockSec) {
        try {
            boolean ret;
            if (ObjectUtils.isEmpty(unlockSec)) {
                ret = cacheService.hincrBy(RedisCacheKeys.getCoopsDistributedLockKey(), lockKey, 1) == 1;
            } else {
                ret = cacheService.hincrByForTime(RedisCacheKeys.getCoopsDistributedLockKey(), lockKey, 1, unlockSec) == 1;
            }
            if (ret) {
                threadLocal.set(lockKey);
            }
            return ret;
        } catch (Exception e) {
            log.error(String.format("分布式加锁出错 lockKey：%s%s", lockKey, ObjectUtils.isEmpty(unlockSec) ? "" : "，unlockSec：" + unlockSec), e);
            return false;
        }
    }

    @Override
    public boolean unlock() {
        try {
            cacheService.hdel(RedisCacheKeys.getCoopsDistributedLockKey(), threadLocal.get());
            threadLocal.remove();
            return true;
        } catch(Exception e) {
            log.error(String.format("分布式解锁出错 lockKey：%s", threadLocal.get()), e);
            return false;
        }
    }
}
