package com.ruoyi.projetctCost.util;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.redis.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock;

/*加锁方法*/
@Slf4j
public class RedisLockMethodUtil {
    private static volatile RedisLockMethodUtil instance;
    private static final ReentrantLock lock = new ReentrantLock();

    public RedisLockMethodUtil() {
    }

    public static RedisLockMethodUtil getInstance() {
        if (instance == null) {
            synchronized (RedisLockMethodUtil.class) {
                if (instance == null) {
                    instance = new RedisLockMethodUtil();
                }
            }
        }
        return instance;
    }

    public BigDecimal redisCacheTaskNoLock(String taskNo, UUID uuid, RedisCache redisCache) {
        lock.lock();
        BigDecimal value = BigDecimal.valueOf(0);
        try {
            Map<String, Object> cacheMap = redisCache.getCacheMapValue(CacheConstants.INSTALLATION_COST, taskNo);

            String cacheStringUUID = null;
            if (cacheMap != null) {
                cacheStringUUID = (String) cacheMap.get(CacheConstants.UUID);
            }
            UUID cacheUUID = null;
            if (cacheStringUUID != null) {
                cacheUUID = UUID.fromString(cacheStringUUID);
            }

            if (ObjectUtils.isEmpty(cacheUUID) || Objects.equals(cacheUUID, new UUID(0L, 0L))) {
                HashMap<String, Object> cache = new HashMap<>();
                cache.put(CacheConstants.UUID, uuid);
                redisCache.setCacheMapValue(CacheConstants.INSTALLATION_COST, taskNo, cache);
            }

            Map<String, Object> taskNoMap = redisCache.getCacheMapValue(CacheConstants.INSTALLATION_COST, taskNo);

            String stringUUID = (String) taskNoMap.get(CacheConstants.UUID);
            UUID redisCacheUUID = UUID.fromString(stringUUID);
            BigDecimal cacheValue = (BigDecimal) taskNoMap.get(CacheConstants.VALUE);

            if (Objects.equals(redisCacheUUID, uuid)) {
                if (Objects.isNull(cacheValue)) {
                    taskNoMap.put(CacheConstants.VALUE, value);
                    redisCache.setCacheMapValue(CacheConstants.INSTALLATION_COST, taskNo, taskNoMap);
                } else {
                    value = cacheValue;
                }
            } else {
                value = BigDecimal.valueOf(-1);
            }
        } finally {
            lock.unlock();
        }
        return value;
    }

    public boolean redisCacheTaskNoUnlock(String taskNo, UUID uuid, BigDecimal value, RedisCache redisCache) {
        HashMap<String, Object> cacheMap = redisCache.getCacheMapValue(CacheConstants.INSTALLATION_COST, taskNo);
        if (ObjectUtils.isEmpty(cacheMap)) return false;

        String stringUUID = (String) cacheMap.get(CacheConstants.UUID);
        UUID cacheUUID = UUID.fromString(stringUUID);
        if (ObjectUtils.isEmpty(cacheUUID) || !Objects.equals(uuid, cacheUUID)) return false;
        cacheMap.put(CacheConstants.UUID, new UUID(0L, 0L));
        cacheMap.put(CacheConstants.VALUE, value);
        redisCache.setCacheMapValue(CacheConstants.INSTALLATION_COST, taskNo,cacheMap);
        return true;
    }
}
