"""RBAC helpers for public-serving deployments."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any


DEFAULT_ROLE_SCOPES: dict[str, set[str]] = {
    "admin": {"*"},
    "operator": {
        "agent:run",
        "state:read",
        "state:write",
        "knowledge:write",
        "quality:read",
        "quality:run",
        "observability:read",
        "learning:read",
        "learning:write",
        "prompt:read",
        "prompt:write",
    },
    "developer": {
        "agent:run",
        "state:read",
        "knowledge:write",
        "quality:read",
        "observability:read",
        "learning:read",
        "prompt:read",
    },
    "viewer": {
        "state:read",
        "quality:read",
        "observability:read",
        "learning:read",
        "prompt:read",
    },
}


@dataclass
class RoleBinding:
    """Maps a named role to one or more scopes."""

    name: str
    scopes: set[str] = field(default_factory=set)


@dataclass
class RBACPolicy:
    """In-memory RBAC policy registry."""

    roles: dict[str, RoleBinding] = field(default_factory=dict)

    def scopes_for_roles(self, roles: list[str] | tuple[str, ...] | set[str]) -> set[str]:
        resolved: set[str] = set()
        for role in roles:
            binding = self.roles.get(role)
            if binding is not None:
                resolved.update(binding.scopes)
        return resolved


def default_rbac_policy() -> RBACPolicy:
    return RBACPolicy(
        roles={
            name: RoleBinding(name=name, scopes=set(scopes))
            for name, scopes in DEFAULT_ROLE_SCOPES.items()
        }
    )


def expand_roles(config: dict[str, Any], policy: RBACPolicy | None = None) -> set[str]:
    role_policy = policy or default_rbac_policy()
    roles = config.get("roles") or []
    role = config.get("role")
    if role:
        roles = [*roles, role]
    return role_policy.scopes_for_roles(roles)


__all__ = [
    "DEFAULT_ROLE_SCOPES",
    "RBACPolicy",
    "RoleBinding",
    "default_rbac_policy",
    "expand_roles",
]
