from django.db import transaction

from .models import Notification

PERSONAL_NOTIFICATION_LIMIT = 200


def notify_project_change(project, actor, kind, text):
    """Notify the project's owner + contributors about a change, excluding the actor.

    Retention: keeps only the newest ~200 notifications per recipient."""
    if actor is None or not actor.is_authenticated:
        return
    recipient_ids = {project.owner_id}
    recipient_ids.update(project.contributors.values_list('user_id', flat=True))
    recipient_ids.discard(actor.pk)
    if not recipient_ids:
        return
    with transaction.atomic():
        for uid in recipient_ids:
            Notification.objects.create(
                user_id=uid, actor=actor, project=project, kind=kind, text=text,
            )
        # Prune each recipient down to the newest limit.
        for uid in recipient_ids:
            stale = list(
                Notification.objects.filter(user_id=uid)
                .order_by('-created_at', '-pk')
                .values_list('pk', flat=True)[PERSONAL_NOTIFICATION_LIMIT:]
            )
            if stale:
                Notification.objects.filter(pk__in=stale).delete()
