package com.jiayue.ssi.job;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jiayue.ssi.constant.CacheConstants;
import com.jiayue.ssi.constant.Constants;
import com.jiayue.ssi.constant.LoginConstants;
import com.jiayue.ssi.dto.ActiveUserDto;
import com.jiayue.ssi.entity.SysLogininfor;
import com.jiayue.ssi.entity.SysUser;
import com.jiayue.ssi.mapper.SysUserMapper;
import com.jiayue.ssi.service.SysLogininforService;
import com.jiayue.ssi.service.SysUserService;
import com.jiayue.ssi.util.*;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

/**
* 自动扫描心跳用户
*
* @author xsl
* @since 2023/04/06
*/
@Service
@EnableScheduling
@Slf4j
public class AutoScanHeartUser {
    @Autowired
    SysUserService sysUserService;
    @Autowired
    SysUserMapper sysUserMapper;
    /**
     * 每2秒扫描一次
     */
    @Scheduled(fixedRate=2000)
    public void autoScanHeartUser() throws Exception{
        Iterator<Map.Entry<String, ActiveUserDto>> activeUserIterator = CacheConstants.ACTIVE_USER_MAP.entrySet().iterator();
        while (activeUserIterator.hasNext()) {
            Map.Entry<String,ActiveUserDto> entry = activeUserIterator.next();
            String username = entry.getKey();
            ActiveUserDto activeUserDto = entry.getValue();
            SysUser sysUser = activeUserDto.getSysUser();

            if (LocalCache.get(CacheConstants.HEART_KEY+username)==null && (System.currentTimeMillis()- activeUserDto.getLoginTime()>5000)){
                // 设置用户离线状态
                LambdaUpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<SysUser>().lambda();
                updateWrapper.eq(SysUser::getId, sysUser.getId()).set(SysUser::getOnlineStatus, "1");
                sysUserMapper.update(new SysUser(), updateWrapper);

                // 记录用户退出日志
                HttpServletRequest request = activeUserDto.getHttpServletRequest();
                final UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
                final String ip = IPUtils.getIpAddr(request);
                String address = AddressUtils.getRealAddressByIP(ip);
                // 获取客户端操作系统
                String os = userAgent.getOperatingSystem().getName();
                // 获取客户端浏览器
                String browser = userAgent.getBrowser().getName();
                // 封装对象
                SysLogininfor logininfor = new SysLogininfor();
                logininfor.setUserName(sysUser.getUsername());
                logininfor.setIpaddr(ip);
                logininfor.setLoginLocation(address);
                logininfor.setBrowser(browser);
                logininfor.setOs(os);
                logininfor.setMsg("退出成功");
                logininfor.setLoginTime(new Date());
                logininfor.setCreateBy(sysUser.getUsername());
                // 日志状态
                logininfor.setStatus(Constants.SUCCESS);
                // 插入数据
                SpringUtils.getBean(SysLogininforService.class).insertLogininfor(logininfor);

                // 将token存储内存中，便于重复登录比对
                CacheConstants.LOGIN_TOKEN_MAP.remove(sysUser.getUsername());
                LoginConstants.sessionMap.remove(sysUser.getUsername());
                CacheConstants.KICKED_USER_MAP.remove(sysUser.getUsername());
                Iterator<Map.Entry<String, String>> ipUserMap = CacheConstants.IP_USER_MAP.entrySet().iterator();
                while (ipUserMap.hasNext()) {
                    Map.Entry<String, String> entry1 = ipUserMap.next();
                    String cacheusername = entry1.getValue();
                    if (cacheusername.equals(entry.getKey())){
                        ipUserMap.remove();
                    }
                }
                activeUserIterator.remove();
            }
        }
    }
}
