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 jdk.nashorn.internal.ir.annotations.Ignore;
import org.apache.commons.compress.utils.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;


public class ISCAuthInterceptor implements HandlerInterceptor{

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


	public ISCAuthInterceptor(SettleContext settleContext, RedisTemplate redisTemplate, BizLocker bizLocker) {
		this.settleContext = settleContext;
		this.redisTemplate = redisTemplate;
		this.bizLocker = bizLocker;
	}

	public ISCAuthInterceptor(){

	}

	@Resource
	protected SettleContext settleContext;

	@Resource
	protected RedisTemplate redisTemplate;

	@Resource
	protected BizLocker bizLocker;

	private Set<String> ignoreURI =
			Sets.newHashSet("login/verify",
					"login/changeRole",
					"login/changeOrg");

	public Set<String> getIgnoreURI() {
		return ignoreURI;
	}

	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
		clearCache();
		String requestURI = request.getRequestURI();
		logger.info("本次请求的url["+requestURI+"]");

		if(ignoreURI.stream().filter(requestURI::startsWith).findFirst().isPresent()){
			return true;
		}
		//
		String token = request.getHeader("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());
		sessionUserVo.setRoleID(loginInfoVO.getCurRole().getId());
		sessionUserVo.setParentRoleID(loginInfoVO.getCurRole().getParentroleid());
		sessionUserVo.setRoleName(loginInfoVO.getCurRole().getName());
//		sessionUserVo.setParentRoleName("");
		settleContext.setSessionUserVo(sessionUserVo);
		settleContext.simpleLoadSettleSession();
		this.clearUserLock(requestURI,sessionUserVo);

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

	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();
	}



	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
		System.out.println("postHandle: " + request.getRequestURI());
	}

	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
		System.out.println("afterCompletion: " + request.getRequestURI());
	}


}
