package com.fs.course.utils;

import cn.hutool.core.util.IdUtil;
import com.fs.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.redisson.api.RLock;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
public class LinkUtil {

    public static String generateRandomStringWithLock() {
        RedissonClient redissonClient = SpringUtils.getBean(RedissonClient.class);
        RLock lock = redissonClient.getLock("generateLinkLock");

        int retryCount = 3;  // 设置重试次数
        int waitTime = 100;  // 等待锁的最大时间（单位：毫秒）
        int leaseTime = 10;  // 锁的持有时间（单位：秒）

        while (retryCount > 0) {
            try {
                // 尝试获取锁，最多等待waitTime毫秒，锁定之后最多持有锁leaseTime秒
                boolean isLocked = lock.tryLock(waitTime, leaseTime, TimeUnit.MILLISECONDS);
                if (isLocked) {
                    // 成功获取锁，生成唯一的随机字符串
                    return IdUtil.getSnowflake(0, 0).nextIdStr();
                } else {
                    // 如果锁未能获取到，重试
                    retryCount--;
                    if (retryCount == 0) {
                        log.warn("Failed to acquire lock after multiple retries.");
                        return generateFallbackId(); // 返回失败标识
                    }
                    // 可以在这里设置重试等待时间
                    Thread.sleep(200); // 等待一段时间后重试
                }
            } catch (InterruptedException e) {
                log.error("Error while acquiring lock", e);
                Thread.currentThread().interrupt(); // 恢复中断状态
                return generateFallbackId();  // 异常情况下返回失败
            }
        }
        return generateFallbackId();  // 如果所有重试都失败，返回失败
    }

    // 备用方案：确保生成的ID唯一（例如使用UUID或其他算法）
    private static String generateFallbackId() {
        // 示例：使用UUID（牺牲有序性，但保证唯一性）
        return UUID.randomUUID().toString().replace("-", "");
    }
}
