package com.lesingle.edu.common.aspect;

import com.lesingle.edu.common.annotation.RequireRole;
import com.lesingle.edu.common.enums.ErrorCode;
import com.lesingle.edu.common.enums.UserRole;
import com.lesingle.edu.common.exception.BusinessException;
import com.lesingle.edu.common.security.SecurityUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Role Check Aspect
 */
@Aspect
@Component
public class RoleAspect {

    @Around("@annotation(com.lesingle.edu.common.annotation.RequireRole)")
    public Object checkRole(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        RequireRole requireRole = method.getAnnotation(RequireRole.class);

        if (requireRole != null && requireRole.value().length > 0) {
            String currentRole = SecurityUtils.getCurrentRole();
            Set<String> allowedRoles = Arrays.stream(requireRole.value())
                    .map(UserRole::getCode)
                    .collect(Collectors.toSet());

            if (!allowedRoles.contains(currentRole)) {
                throw new BusinessException(ErrorCode.PERMISSION_DENIED);
            }
        }

        return joinPoint.proceed();
    }

}
