package com.cirle.scientific.config;/*
 *24901
 *2022/10/8
 *22:00
 */


import com.cirle.scientific.constants.RedisKeyConstants;
import com.cirle.scientific.utils.StringContextUtil;
import com.cirle.scientific.utils.redis.DistributedLockCache;
import com.cirle.scientific.utils.redis.QkLock;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;
import java.util.Set;
import java.util.concurrent.TimeUnit;


@Slf4j
@Configuration
@WebListener
public class OnlineSessionListener implements HttpSessionListener, ServletContextListener,ServletRequestListener {



    private StringRedisTemplate stringRedisTemplate;



    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        int online = 1;
        HttpSession session = httpSessionEvent.getSession();
        QkLock qkLock = new QkLock();
        qkLock.setName("soles "+session.getId());
        qkLock.setValue(session.getId());
        if(stringRedisTemplate == null){
            stringRedisTemplate = StringContextUtil.getBean(StringRedisTemplate.class);
        }
        String onlineNumber = stringRedisTemplate.opsForValue().get(RedisKeyConstants.redisOnlinePerson);
        try {
            boolean b = soleVerify(qkLock , 2);
            if(b){
                if (!StringUtils.isBlank(onlineNumber) && Integer.parseInt(onlineNumber) >= 1) {
                    online = online + Integer.parseInt(onlineNumber);
                }
                stringRedisTemplate.opsForValue().set(RedisKeyConstants.redisOnlinePerson, String.valueOf(online));
                log.info("新增一位在线用户！"+ session.getId() + "在线用户为" + online + "人");
            }else{
                log.info("重复了一位在线用户！"+ session.getId()+ "在线用户为" + online + "人");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("新增在线用户出现异常 e->{}" ,  e);
        }
    }


    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        int online = 1;
        HttpSession session = se.getSession();
        if(stringRedisTemplate == null){
            stringRedisTemplate = StringContextUtil.getBean(StringRedisTemplate.class);
        }
        String onlineNumber = stringRedisTemplate.opsForValue().get(RedisKeyConstants.redisOnlinePerson);
        if(onlineNumber == null || Integer.parseInt(onlineNumber) == 1){
            stringRedisTemplate.opsForValue().set(RedisKeyConstants.redisOnlinePerson, String.valueOf(1));
        }else{
            online = Integer.parseInt(onlineNumber) - online;
            stringRedisTemplate.opsForValue().set(RedisKeyConstants.redisOnlinePerson, String.valueOf(online));
        }
        log.info("一位用户离线"+ session.getId() + "在线用户为" + online + "人");
    }

    /**
     *
     * @param lock 要锁的key 和 value
     * @param lockExpireTime 保存redis的有效期
     * @return 保存成功返回true 失败false
     */
    public boolean soleVerify(QkLock lock, long lockExpireTime){
        try {
            if (stringRedisTemplate.opsForValue().setIfAbsent(lock.getName(), lock.getValue())) {
                Boolean flag = stringRedisTemplate.expire(lock.getName(), lockExpireTime, TimeUnit.MINUTES);
                return flag;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("锁报错了  e->{}",e);
        }
        return false;
    }
}
