package com.yunzhupaas.filter;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.filter.SaFilterAuthStrategy;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.yunzhupaas.base.ActionResultCode;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.consts.AuthConsts;
import com.yunzhupaas.properties.GatewayWhite;
import com.yunzhupaas.util.IpUtil;
import com.yunzhupaas.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 * 网关验证token
 *
 * @author 云筑产品开发平台组
 * @version V3.1.0
 * @copyright 深圳市乐程软件有限公司（http://www.szlecheng.cn）
 * @date 2024-03-24
 */
@Slf4j
@Configuration
public class AuthFilter {


    @Autowired
    private GatewayWhite gatewayWhite;

    @Autowired
    private SaFilterAuthStrategy defaultBeforeAuthStrategy;

    // 注册 Sa-Token全局过滤器
    @Bean
    public SaServletFilter getSaReactorFilter() {
        return new SaServletFilter()
                // 拦截地址
                .addInclude("/**")
                .setExcludeList(gatewayWhite.excludeUrl)
                // 鉴权方法：每次访问进入
                .setAuth(obj -> {
                    if(log.isInfoEnabled()){
                        log.info("请求路径: {}", SaHolder.getRequest().getRequestPath());
                    }
                    //拦截路径
                    SaRouter.match(gatewayWhite.blockUrl).match(o -> {
                        //禁止访问URL 排除白名单
                        String ip = getIpAddr();
                        for (String o1 : gatewayWhite.whiteIp) {
                            if(ip.startsWith(o1)){
                                return false;
                            }
                        }
                        log.info("非白名单IP访问限制接口：{}, {}", SaHolder.getRequest().getRequestPath(), ip);
                        return true;
                    }).back(MsgCode.AD101.get());
                    //测试不验证 鉴权服务重启测试模式不清除Token就够了
                    //SaRouter.match((r)->"true".equals(configValueUtil.getTestVersion())).stop();
                    //白名单不拦截
                    SaRouter.match(gatewayWhite.whiteUrl).stop();
                    //内部请求不拦截
                    SaRouter.match(t->{
                        String innerToken = SaHolder.getRequest().getHeader(AuthConsts.INNER_TOKEN_KEY);
                        return UserProvider.isValidInnerToken(innerToken);
                    }).stop();
                    // 登录校验 -- 校验多租户管理模块TOKEN
                    //SaRouter.match("/api/tenant/**", r -> {
                    //    SaManager.getStpLogic(AuthConsts.ACCOUNT_TYPE_TENANT).checkLogin();
                    //}).stop();
                    // 登录校验 -- 拦截所有路由
                    SaRouter.match("/**", r -> {
                        StpUtil.checkLogin();
                    }).stop();
                }).setError(e -> {
                    SaHolder.getResponse().addHeader("Content-Type","application/json; charset=utf-8");
                    if(e instanceof NotLoginException){
                        return SaResult.error(ActionResultCode.SessionOverdue.getMessage()).setCode(ActionResultCode.SessionOverdue.getCode());
                    }
                    log.error(e.getMessage(), e);
                    return SaResult.error(MsgCode.AD102.get()).setCode(ActionResultCode.Exception.getCode());
                })
                // 前置函数：在每次认证函数之前执行
                .setBeforeAuth(defaultBeforeAuthStrategy);
    }



    public static String getIpAddr() {
        return IpUtil.getIpAddr();
    }


}

