"""All Redis key and channel name patterns — no string literals elsewhere."""

from __future__ import annotations


def task_key(project_id: str, task_id: str) -> str:
    """Redis hash key for a single task."""
    return f"loom:{project_id}:task:{task_id}"


def status_set(project_id: str, status: str) -> str:
    """Redis set of task IDs in a given status."""
    return f"loom:{project_id}:tasks:{status}"


def ready_queue(project_id: str) -> str:
    """Redis sorted set of ready tasks scored by priority."""
    return f"loom:{project_id}:tasks:ready"


def event_stream(project_id: str) -> str:
    """Redis Stream for ordered, persistent events."""
    return f"loom:{project_id}:events"


def updates_channel(project_id: str) -> str:
    """Pub/sub channel for any task state change."""
    return f"loom:{project_id}:tasks:updates"


def escalation_channel(project_id: str) -> str:
    """Pub/sub channel for new escalations."""
    return f"loom:{project_id}:escalations"


def agent_channel(project_id: str, agent_id: str) -> str:
    """Pub/sub channel for direct messages to an agent."""
    return f"loom:{project_id}:messages:{agent_id}"


def broadcast_channel(project_id: str) -> str:
    """Pub/sub channel for messages to all agents."""
    return f"loom:{project_id}:broadcast"


def escalation_queue(project_id: str) -> str:
    """Redis list used as escalation queue (LPUSH/BRPOP)."""
    return f"loom:{project_id}:escalation_queue"


# Phase 3: Orchestration keys

def claim_ttl_key(project_id: str) -> str:
    """Redis sorted set tracking claim expiry times for sweep."""
    return f"loom:{project_id}:claims:ttl"


def dead_letter_set(project_id: str) -> str:
    """Redis set of permanently failed task IDs."""
    return f"loom:{project_id}:tasks:dead_letter"


def workflow_channel(project_id: str) -> str:
    """Pub/sub channel for workflow state changes."""
    return f"loom:{project_id}:workflows"


# Phase 5: Multi-project keys

def project_list_key() -> str:
    """Redis sorted set for quick project listing."""
    return "loom:projects"


def project_config_key(project_id: str) -> str:
    """Redis hash for cached project config."""
    return f"loom:{project_id}:config"


# Phase 6: Merge agent keys

MERGE_LOCK_KEY = "loom:lock:merge:main"  # distributed lock for merge-to-main operations


def merge_spawned_key(project_id: str, task_id: str) -> str:
    """Redis key for merge task idempotency guard (SETNX with TTL)."""
    return f"loom:{project_id}:merge:spawned:{task_id}"


# Phase 7: Escalation cleanup keys

def escalation_guard_key(project_id: str, task_id: str) -> str:
    """Redis key for escalation dedup guard (SETNX with TTL)."""
    return f"loom:{project_id}:escalation:guard:{task_id}"


# Phase 7: Agent progress tracking

def task_progress_key(project_id: str, task_id: str) -> str:
    """Redis key for agent progress data on a task."""
    return f"loom:{project_id}:task:{task_id}:progress"
