package cn.reghao.tnb.account.app.aop;

import cn.reghao.jutil.web.ServletUtil;
import cn.reghao.tnb.account.api.constant.TokenType;
import cn.reghao.tnb.account.app.security.form.AccountAuthToken;
import cn.reghao.tnb.account.app.service.AccountTokenService;
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.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author reghao
 * @date 2023-07-18 15:17:35
 */
@Component
@Aspect
@Deprecated
public class AuthUserAspect {
    private final String cookieName = "USERDATA";
    private final AccountTokenService accountTokenService;

    public AuthUserAspect(AccountTokenService accountTokenService) {
        this.accountTokenService = accountTokenService;
    }

    @Pointcut("@annotation(cn.reghao.tnb.account.app.aop.AuthUser)")
    public void loginPointCut(){
    }

    @Around("loginPointCut()")
    public Object tokenHandler(ProceedingJoinPoint point) throws Throwable {
        Class<?> aClass = point.getTarget().getClass();
        MethodSignature ms = (MethodSignature)point.getSignature();
        Method method = aClass.getDeclaredMethod(ms.getName(),ms.getParameterTypes());
        AuthUser authUser = method.getAnnotation(AuthUser.class);

        String userdata = ServletUtil.getCookie(cookieName);
        if (userdata != null) {
            AccountAuthToken authToken = accountTokenService.getAuthToken(TokenType.cookie.getValue(), userdata);
            if (authToken != null) {
                SecurityContext context = SecurityContextHolder.createEmptyContext();
                context.setAuthentication(authToken);
            } else {
                SecurityContextHolder.createEmptyContext();
                accountTokenService.clearCookie();
            }
        } else {
            SecurityContextHolder.createEmptyContext();
        }

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        boolean auth = authUser.value();
        if (auth && authentication instanceof AccountAuthToken) {
            return point.proceed(point.getArgs());
        }

        throw new AuthException("接口需要认证后才可访问");
    }
}
