"""权限校验守卫测试."""

import pytest

from src.ai.errors import AIError, ErrorCode
from src.ai.middleware.auth import UserContext
from src.ai.middleware.permission import (
    PERMISSION_AI_CHAT,
    PERMISSION_AI_LESSON_CONFIRM,
    PERMISSION_AI_LESSON_GENERATE,
    PERMISSION_AI_QUESTION_GENERATE,
    PermissionGuard,
)


class TestPermissionGuard:
    """PermissionGuard 测试."""

    def test_dev_mode_skips_check(self) -> None:
        """dev_mode=true 跳过校验."""
        guard = PermissionGuard(dev_mode=True)
        ctx = UserContext()  # 未认证
        # 不抛异常即通过
        guard.check(ctx, PERMISSION_AI_CHAT)

    def test_unauthenticated_raises(self) -> None:
        """未认证用户抛 AI_UNAUTHORIZED."""
        guard = PermissionGuard(dev_mode=False)
        ctx = UserContext()
        with pytest.raises(AIError) as exc_info:
            guard.check(ctx, PERMISSION_AI_CHAT)
        assert exc_info.value.code == ErrorCode.AI_UNAUTHORIZED

    def test_teacher_has_all_permissions(self) -> None:
        """teacher 角色拥有全部权限."""
        guard = PermissionGuard(dev_mode=False)
        ctx = UserContext(user_id="u-1", role="teacher")
        guard.check(ctx, PERMISSION_AI_CHAT)
        guard.check(ctx, PERMISSION_AI_QUESTION_GENERATE)
        guard.check(ctx, PERMISSION_AI_LESSON_GENERATE)
        guard.check(ctx, PERMISSION_AI_LESSON_CONFIRM)

    def test_student_only_chat(self) -> None:
        """student 角色仅有 chat 权限."""
        guard = PermissionGuard(dev_mode=False)
        ctx = UserContext(user_id="u-1", role="student")
        guard.check(ctx, PERMISSION_AI_CHAT)
        with pytest.raises(AIError) as exc_info:
            guard.check(ctx, PERMISSION_AI_QUESTION_GENERATE)
        assert exc_info.value.code == ErrorCode.AI_FORBIDDEN

    def test_unknown_role_defaults_student(self) -> None:
        """未知角色降级为 student 权限."""
        guard = PermissionGuard(dev_mode=False)
        ctx = UserContext(user_id="u-1", role="guest")
        guard.check(ctx, PERMISSION_AI_CHAT)
        with pytest.raises(AIError):
            guard.check(ctx, PERMISSION_AI_LESSON_GENERATE)

    def test_empty_role_defaults_student(self) -> None:
        """空角色降级为 student."""
        guard = PermissionGuard(dev_mode=False)
        ctx = UserContext(user_id="u-1", role="")
        guard.check(ctx, PERMISSION_AI_CHAT)
        with pytest.raises(AIError):
            guard.check(ctx, PERMISSION_AI_QUESTION_GENERATE)

    def test_forbidden_includes_details(self) -> None:
        """权限拒绝 details 含 required_permission + role."""
        guard = PermissionGuard(dev_mode=False)
        ctx = UserContext(user_id="u-1", role="student")
        with pytest.raises(AIError) as exc_info:
            guard.check(ctx, PERMISSION_AI_LESSON_CONFIRM)
        assert exc_info.value.details["required_permission"] == PERMISSION_AI_LESSON_CONFIRM
        assert exc_info.value.details["role"] == "student"
