"""Claim TTL sweep — releases tasks from crashed/stuck agents."""

from __future__ import annotations

import asyncpg
from redis.asyncio import Redis

from loom.bus.events import EventType
from loom.bus.publisher import publish_event
from loom.graph import cache, store


async def sweep_expired_claims(
    pool: asyncpg.Pool,
    redis: Redis,
    project_id: str,
) -> int:
    """Find and release all tasks with expired claim TTLs.

    For each expired claim:
    1. Release the claim (claimed -> pending, clear assignee)
    2. Sync to Redis cache
    3. Add back to ready queue
    4. Publish CLAIM_EXPIRED event

    Returns the number of tasks released.
    """
    expired = await store.get_expired_claims(pool, project_id)
    released = 0
    for task in expired:
        released_task = await store.release_expired_claim(pool, task.id)
        await cache.sync_task(redis, released_task)
        await cache.add_to_ready_queue(redis, released_task)
        await publish_event(redis, project_id, EventType.CLAIM_EXPIRED, task.id)
        released += 1
    return released
