package cn.superdesk.uniorder.common.security.openapi.interceptor.AuthorityVerify;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.superdesk.uniorder.common.constants.BaseMessageConf;
import cn.superdesk.uniorder.common.constants.BaseSysConf;
import cn.superdesk.uniorder.common.constants.ResponseResultConstants;
import cn.superdesk.uniorder.common.mq.redis.service.RedisManager;
import cn.superdesk.uniorder.common.numerical.AnStringUtils;
import cn.superdesk.uniorder.common.rest.response.ResponseResultOuterUtils;
import cn.superdesk.uniorder.common.security.JwtUtil;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

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

/**
 * @Description: 权限校验 切面实现
 * @Author: linjinyu
 * @CreateDate: 2021/6/2 下午6:01
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/6/2 下午6:01
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Aspect
@Component
@Slf4j
public class AuthorityVerifyAspect {

	@Autowired
	private RedisManager redisManager;

	@Pointcut(value = "@annotation(authorityVerify)")
	public void pointcut(AuthorityVerify authorityVerify) {

	}

	@Around(value = "pointcut(authorityVerify)")
	public Object doAround(ProceedingJoinPoint joinPoint, AuthorityVerify authorityVerify) throws Throwable {

		ServletRequestAttributes attribute = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

		HttpServletRequest request = attribute.getRequest();

		// 获取请求路径
		String requestURI = request.getRequestURI();
		// 解析出请求者的 accessToken
//		String accessToken = AnStringUtils.getString(request.getAttribute(BaseSysConf.TOKEN));
		String accessToken = AnStringUtils.getString(request.getHeader(BaseSysConf.TOKEN));

		if (StrUtil.isBlank(accessToken)) {
			return ResponseResultOuterUtils.createErrorResult(ResponseResultConstants.NO_OPERATION_AUTHORITY, BaseMessageConf.RESTAPI_NO_PRIVILEGE);
		}

		// TODO 根据accessToken,得出 LoginSysUser
		LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(accessToken);

		if (ObjectUtil.isNull(loginSysUser)) {
			return ResponseResultOuterUtils.createErrorResult(ResponseResultConstants.NO_OPERATION_AUTHORITY, BaseMessageConf.RESTAPI_NO_PRIVILEGE);
		}

//		log.info("权限 \n{}\n{}\n{}", requestURI, accessToken, JSONUtil.toJsonStr(loginSysUser));

		// TODO 管理员能够访问的路径
//		String visitUrlStr = redisUtil.get(BaseRedisConf.OPEN_API_VISIT_MENU + BaseRedisConf.SEGMENTATION + loginSysUser.getSysUserName());
//		LinkedTreeMap<String, String> visitMap = new LinkedTreeMap<>();
//		// 从Redis中获取
//		if (StrUtil.isNotBlank(visitUrlStr)) {
//			// TODO ...
//		}
//		// 从Mysql中获取 还是不要从数据库取了
//		else {
//			// TODO ...
//			// 将访问URL存储到Redis中
//		}


		Map<String, String> visitMap = redisManager.getPermissionOpenApiCache(loginSysUser.getSysUserName());

//		log.info("权限 \n{}", JSONUtil.toJsonStr(visitMap));

		// 处理前缀
		String urlReplace = requestURI.replace("/web", "");


		// 判断该角色是否能够访问该接口
		if (visitMap.get(urlReplace) != null) {

			log.info("用户拥有操作权限,访问的路径: {},拥有的权限接口:{}", requestURI, visitMap.get(urlReplace));

			// 执行业务
			return joinPoint.proceed();
		} else {

			log.info("用户不具有操作权限,访问的路径: {}, 不拥有的权限接口: {} {}", requestURI, urlReplace, visitMap.get(urlReplace));

			return ResponseResultOuterUtils.createErrorResult(ResponseResultConstants.NO_OPERATION_AUTHORITY, BaseMessageConf.RESTAPI_NO_PRIVILEGE);
		}
	}

}
