package com.bonus.common.security.aspect;

import com.alibaba.nacos.plugin.auth.constant.Constants;
import com.bonus.common.core.constant.SecurityConstants;
import com.bonus.common.core.exception.InnerAuthException;
import com.bonus.common.core.utils.ServletUtils;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.security.annotation.*;
import com.bonus.common.security.auth.AuthUtil;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 内部服务调用验证处理
 * 
 * @author bonus
 */
@Aspect
@Component
public class PermissionOrInnerAuthAspect
{
    @Pointcut("@annotation(com.bonus.common.security.annotation.RequiresPermissionsOrInnerAuth)")
    public void permissionOrInnerAuthAspect() {}

    @Around("permissionOrInnerAuthAspect()")
    public Object innerAround(ProceedingJoinPoint point) throws Throwable
    {
        MethodSignature signature = (MethodSignature) point.getSignature();
        RequiresPermissionsOrInnerAuth auth = signature.getMethod().getAnnotation(RequiresPermissionsOrInnerAuth.class);

        // 获取内部认证注解
        InnerAuth innerAuth = auth.innerAuth();
        // 获取权限注解
        RequiresPermissions requiresPermissions = auth.requiresPermissions();

        // 检查内部认证
        if (isInnerAuthPassed(innerAuth)) {
            return point.proceed();
        }

        // 检查权限
        if (isPermissionsPassed(requiresPermissions,point)) {
            return point.proceed();
        }

        throw new RuntimeException("认证或权限校验失败");
    }

    private boolean isInnerAuthPassed(InnerAuth innerAuth) {
        try {
            AuthUtil.checkInnerAuth(innerAuth);
        } catch (InnerAuthException e){
//            log.error("内部认证失败:{}",e.getMessage());
            return false;
        }
        return true;
    }

    private boolean isPermissionsPassed(RequiresPermissions requiresPermissions,ProceedingJoinPoint point) {
        AuthUtil.checkPermi(requiresPermissions,point);
        return true;
    }

//    /**
//     * 确保在权限认证aop执行前执行
//     */
//    @Override
//    public int getOrder()
//    {
//        return Ordered.HIGHEST_PRECEDENCE + 2;
//    }
}
