package com.inspect.common.security.aspect;

import com.inspect.common.security.annotation.RequiresLogin;
import com.inspect.common.security.annotation.RequiresPermissions;
import com.inspect.common.security.annotation.RequiresRoles;
import com.inspect.common.security.auth.AuthUtil;

import java.lang.reflect.Method;

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.stereotype.Component;

@Aspect
@Component
public class PreAuthorizeAspect {
    public static final String POINTCUT_SIGN = " @annotation(com.inspect.common.security.annotation.RequiresLogin) || @annotation(com.inspect.common.security.annotation.RequiresPermissions) || @annotation(com.inspect.common.security.annotation.RequiresRoles)";

    @Pointcut(" @annotation(com.inspect.common.security.annotation.RequiresLogin) || @annotation(com.inspect.common.security.annotation.RequiresPermissions) || @annotation(com.inspect.common.security.annotation.RequiresRoles)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        this.checkMethodAnnotation(signature.getMethod());

        try {
            Object obj = joinPoint.proceed();
            return obj;
        } catch (Throwable throwable) {
            throw throwable;
        }
    }

    public void checkMethodAnnotation(Method method) {
        RequiresLogin requiresLogin = method.getAnnotation(RequiresLogin.class);
        if (requiresLogin != null) {
            AuthUtil.checkLogin();
        }

        RequiresRoles requiresRoles = method.getAnnotation(RequiresRoles.class);
        if (requiresRoles != null) {
            AuthUtil.checkRole(requiresRoles);
        }

        RequiresPermissions requiresPermissions = method.getAnnotation(RequiresPermissions.class);
        if (requiresPermissions != null) {
            AuthUtil.checkPermission(requiresPermissions);
        }

    }
}
