package com.engine.htsc.seal.web;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import redis.clients.jedis.Jedis;
import redis.clients.util.Pool;
import weaver.session.util.RedisTemplate;

import java.util.Collections;

@Slf4j
/**
 * <p>Redis相关工具</p>
 * @title RedisTools
 * @author K1810015
 * @updateTime 2022/9/19 20:14
 */
public class RedisTools {



    private static final String LOCK_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "PX";
    private static final Long RELEASE_SUCCESS = 1L;
    private static final Long REDIS_COMMAND_TIMEOUT=1000L;


    public static Jedis GetJedis(){
        RedisTemplate redisTemplate = new RedisTemplate();
        Pool<Jedis> jedisPool =  redisTemplate.getJedisPool();
        Jedis jedis = jedisPool.getResource();
        return jedis;
    }



    /**
     * 尝试获取分布式锁
     * @param jedis Redis客户端
     * @param lockKey 锁
     * @param requestId 请求标识
     * @param expireTime 超期时间
     * @return 是否获取成功
     */
    public static boolean TryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {
        String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);

        if (LOCK_SUCCESS.equals(result)) {
            return true;
        }
        return false;

    }

    /**
     * <p>获取redis锁</p>
     * @title getDistributedLock
     * @author K1810015
     * @updateTime 2022/9/19 16:57
     * @param jedis  jedis
     * @param lockKey 锁名
     * @param requestId requestid
     * @param expireTime
     * @param retryTimes 等待次数
     * @param sleepMillis  等待暂停时间
     */
    public static boolean getDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime, int sleepMillis, int retryTimes) {
        boolean result = TryGetDistributedLock(jedis, lockKey, requestId, expireTime);
        // 如果获取锁失败，按照传入的重试次数进行重试
        while ((!result) && retryTimes-- > 0) {
            try {
                log.debug("retryTimes:"+retryTimes+"lockKey:" + lockKey+" requestId:"+requestId);
                Thread.sleep(sleepMillis);
            } catch (InterruptedException e) {
                log.error("InterruptedException", e);
                // Restore interrupted state...
                Thread.currentThread().interrupt();
                return false;
            }
            result = TryGetDistributedLock(jedis, lockKey, requestId, expireTime);
        }
        return result;
    }
    /**
     * 释放分布式锁
     * @param jedis Redis客户端
     * @param lockKey 锁
     * @param requestId 请求标识
     * @return 是否释放成功
     */
    public static boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Object result = jedis.eval(script, Collections.singletonList(lockKey),  Collections.singletonList(requestId));
        if (RELEASE_SUCCESS.equals(result)) {
            return true;
        }
        return false;

    }

    private GenericObjectPoolConfig getGenericObjectPoolConfig() {
        GenericObjectPoolConfig genericObjectPool = new GenericObjectPoolConfig();
        genericObjectPool.setMaxIdle(10);
        genericObjectPool.setMaxTotal(100);
        // 逐出连接的最小空闲时间 30s
        genericObjectPool.setMinEvictableIdleTimeMillis(30000);
        // 空闲逐出时间1分钟
        genericObjectPool.setSoftMinEvictableIdleTimeMillis(60000);
        return genericObjectPool;
    }



}

