"""In-code permission registry, synced to the DB on `post_migrate`.

Each app declares its permissions by calling `register_permission(...)` from
its `apps.ready()` hook (Phase 7 modules will do this). For Phase 2 we only
seed a tiny core set so the engine has something to bind against in tests.
"""

from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True)
class PermissionSpec:
    codename: str
    label: str
    module: str
    resource: str
    action: str
    description: str = ""


_REGISTRY: dict[str, PermissionSpec] = {}


def register_permission(
    codename: str,
    *,
    label: str,
    description: str = "",
) -> PermissionSpec:
    parts = codename.split(".")
    if len(parts) != 3:
        raise ValueError(f"permission codename must be 'module.resource.action', got {codename!r}")
    module, resource, action = parts
    spec = PermissionSpec(
        codename=codename,
        label=label,
        module=module,
        resource=resource,
        action=action,
        description=description,
    )
    _REGISTRY[codename] = spec
    return spec


def registered_permissions() -> list[PermissionSpec]:
    return list(_REGISTRY.values())


def sync_registry_to_db() -> int:
    """Upsert all registered permissions into the DB. Idempotent."""

    from simorgh.apps.iam.models import Permission

    created_or_updated = 0
    for spec in _REGISTRY.values():
        _, was_created = Permission.objects.update_or_create(
            codename=spec.codename,
            defaults={
                "label": spec.label,
                "module": spec.module,
                "resource": spec.resource,
                "action": spec.action,
                "description": spec.description,
            },
        )
        if was_created:
            created_or_updated += 1
    return created_or_updated


# ---------------------------------------------------------------------------
# Core seed — minimal permissions used by the platform itself.
# ---------------------------------------------------------------------------
register_permission("iam.role.view", label="View roles")
register_permission("iam.role.manage", label="Manage roles")
register_permission("iam.user.view", label="View users")
register_permission("iam.user.manage", label="Manage users")
register_permission("iam.permission.view", label="View permissions")
register_permission("tenants.tenant.view", label="View tenant")
register_permission("tenants.tenant.manage", label="Manage tenant")
register_permission("organizations.node.view", label="View organization nodes")
register_permission("organizations.node.manage", label="Manage organization nodes")
register_permission("memberships.membership.view", label="View memberships")
register_permission("memberships.membership.manage", label="Manage memberships")
register_permission("app_settings.setting.view", label="View settings")
register_permission("app_settings.setting.manage", label="Manage settings")
