package com.brilliance.isc.common.filter;

import com.alibaba.fastjson.JSON;
import com.brilliance.isc.common.api.bch.service.impl.BchServiceImpl;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.lock.BizLocker;
import com.brilliance.isc.common.login.res.LoginCacheVo;
import com.brilliance.isc.common.login.vo.LoginInfoVO;
import com.brilliance.isc.exception.RestBizException;
import com.brilliance.isc.vo.manager.SessionUserVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import java.io.IOException;
import java.util.concurrent.TimeUnit;


public class ISCRequestPreFilter implements ContainerRequestFilter {

    Logger logger = LoggerFactory.getLogger(ISCRequestPreFilter.class);

    @Context
    protected HttpServletRequest request;
    @Context
    protected HttpHeaders header;



    @Resource
    protected SettleContext settleContext;

    @Resource
    protected RedisTemplate redisTemplate;

    @Resource
    protected BizLocker bizLocker;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        clearCache();
        String requestURI = request.getRequestURI();
        logger.info("本次请求的url["+requestURI+"]");

        if (requestURI.contains("login/verify") || requestURI.contains("login/changeRole") || requestURI.contains("login/changeOrg")){
            return;
        }
        //
        String token = requestContext.getHeaderString("token");
        Long currentExpireTime = redisTemplate.getExpire(token);
        //判断token是否失效，失效则抛异常
        if(token == null || token.isEmpty() || currentExpireTime<=0){
            throw RestBizException.TOKEN_EXPIRED;
        }
        String loginCache = (String) redisTemplate.opsForValue().get(token);
        LoginCacheVo loginCacheVo = JSON.parseObject(loginCache, LoginCacheVo.class);
        LoginInfoVO loginInfoVO = loginCacheVo.getLoginInfo();

        //session
        SessionUserVo sessionUserVo = new SessionUserVo();
        sessionUserVo.setId(loginInfoVO.getUserId());
        sessionUserVo.setName(loginInfoVO.getUsr().getName());
        sessionUserVo.setLogName(loginInfoVO.getUsername());
        sessionUserVo.setWorkOrg(loginInfoVO.getAccbchList().getBranch());
        sessionUserVo.setOwnOrgDepartmentNumber(loginInfoVO.getCurrentOrg().getDepartmentNumber());
        settleContext.setSessionUserVo(sessionUserVo);
        settleContext.simpleLoadSettleSession();
        this.clearUserLock(requestURI,sessionUserVo);

        //没失效则刷新redis的过期时间（120分钟）
        redisTemplate.expire(token,120, TimeUnit.MINUTES);
        logger.info("将用户的部分信息存入sessionUserVo中");
    }

    private void clearUserLock(String requestURI,SessionUserVo sessionUserVo){
        if(requestURI.indexOf("/logout") > -1){
            logger.info("退出释放等钱用户锁");
            bizLocker.unlockAllOfUser(sessionUserVo.getLogName());
            logger.info("Filter中锁释放完毕");
        }
    }

    /**
     * 避免因为异常导致ThreadLocal未被清理
     */
    private void clearCache(){
        SettleContext.removeUserSession();
        SettleContext.removeSessionUserVo();
        BchServiceImpl.removeBranchCacheMap();
        BchServiceImpl.removeBchInrCacheMap();
    }
}
