package com.ruoyi.cai.ws.cache;

import com.ruoyi.cai.ws.constant.RedisConstant;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class CallerRoomCache {
    @Autowired
    private StringRedisTemplate redisTemplate;

    public String getKey(Long fromUserId){
        return String.format(RedisConstant.CALLER_ROOM_DATA,fromUserId);
    }

    public Long getRoomId(Long fromUserId, Long toUserId){
        String key = getKey(fromUserId);
        Object roomId = redisTemplate.opsForHash().get(key, toUserId);
        return roomId == null ? null : Long.valueOf(roomId.toString());
    }

    public void addRoom(Long fromUid, Long toUid, Long roomId) {
        String key = getKey(fromUid);
        redisTemplate.opsForHash().put(key,toUid,roomId);
        redisTemplate.expire(key,7, TimeUnit.DAYS);
    }

    public Map<Object,Object> getAll(Long fromUid){
        String key = getKey(fromUid);
        return redisTemplate.opsForHash().entries(key);
    }

    public void del(Long fromUid) {
        String key = getKey(fromUid);
        redisTemplate.delete(key);
    }

    private final static String DEL_ROOM_LUA = "return KEYS[1]\n" +
            "local r = tonumber(redis.call('hget',KEYS[1],ARGV[1]))\n" +
            "if r == tonumber(ARGV[2]) then\n" +
            "   return redis.call('hdel',KEYS[1],ARGV[1])\n" +
            "end\n" +
            "return 0";

    public boolean delRoom(Long receiverId, Long roomId) {
        DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(DEL_ROOM_LUA,Boolean.class);
        Boolean execute = redisTemplate.execute(redisScript, Collections.singletonList(getKey(roomId)), receiverId,roomId);
        return BooleanUtils.isTrue(execute);
    }
}
