"""DRF permission classes for MEL API endpoints.

Mirrors the role-based view mixins in :mod:`apps.core.permissions.mixins`.
"""
from __future__ import annotations

from rest_framework.permissions import BasePermission

from apps.core.permissions.roles import UserRole


OFFICER_ROLES = frozenset({
    UserRole.MEL_OFFICER.value,
    UserRole.ADMIN.value,
    UserRole.SYSTEM_ADMIN.value,
})

PROGRAMME_VIEW_ROLES = OFFICER_ROLES | frozenset({
    UserRole.PROGRAM_MANAGER.value,
    UserRole.PROGRAM_DIRECTOR.value,
    UserRole.GRANTS_MANAGER.value,
})


class _RolePermission(BasePermission):
    """Base class — subclasses set ``roles`` to a frozenset of role values."""

    roles: frozenset[str] = frozenset()

    def has_permission(self, request, view):
        user = getattr(request, "user", None)
        if not user or not user.is_authenticated:
            return False
        if user.is_superuser:
            return True
        return getattr(user, "role", "") in self.roles


class IsMelOfficer(_RolePermission):
    """Write-capable MEL roles (Officer, Admin, System Admin)."""

    roles = OFFICER_ROLES


class CanViewMelData(_RolePermission):
    """Read-access for officer roles plus programme managers and grants managers."""

    roles = PROGRAMME_VIEW_ROLES
