"""
AIVA RLM Nexus — Redis Key Schema
Single source of truth for all Redis keys, patterns, and TTLs.
Story 1.03 — Track A

VERIFICATION_STAMP
Story: 1.03
Verified By: parallel-builder
Verified At: 2026-02-25
Tests: 9/9
Coverage: 100%
"""
from dataclasses import dataclass
from typing import Optional
import re


@dataclass(frozen=True)
class RedisKeySchema:
    """All Redis keys used in AIVA RLM Nexus. Single source of truth."""

    # Key patterns (use .format() or build_key() to build)
    AIVA_WORKING_STATE      = "aiva:state:{session_id}"
    AIVA_TRANSCRIPT         = "aiva:transcript:{session_id}"
    AIVA_CONTEXT_PRELOAD    = "aiva:context:{session_id}"
    GENESIS_STAGING         = "genesis:staging:{task_id}"
    GENESIS_MASTER_STATE    = "genesis:state:master:{session_id}"
    GENESIS_SWARM_TASKS     = "genesis:royal:swarm_tasks"
    AIVA_RESULTS            = "aiva:results:{session_id}"
    KINAN_ACTIVE_DIRECTIVES = "kinan:directives:active"

    # TTL policies (seconds)
    TTL_WORKING_STATE    = 86400  # 24 hours
    TTL_TRANSCRIPT       = 3600   # 1 hour (cleaned up after enrichment)
    TTL_CONTEXT_PRELOAD  = 300    # 5 minutes
    TTL_STAGING          = 600    # 10 minutes
    # GENESIS_SWARM_TASKS and KINAN_ACTIVE_DIRECTIVES: no TTL (persistent)
    # AIVA_RESULTS: no TTL (pub/sub channel, auto-expires with subscriber)


# All key patterns for validation
_KEY_PATTERNS = [
    r"^aiva:state:[a-zA-Z0-9_-]+$",
    r"^aiva:transcript:[a-zA-Z0-9_-]+$",
    r"^aiva:context:[a-zA-Z0-9_-]+$",
    r"^genesis:staging:[a-zA-Z0-9_-]+$",
    r"^genesis:state:master:[a-zA-Z0-9_-]+$",
    r"^genesis:royal:swarm_tasks$",
    r"^aiva:results:[a-zA-Z0-9_-]+$",
    r"^kinan:directives:active$",
]
_COMPILED_PATTERNS = [re.compile(p) for p in _KEY_PATTERNS]


def build_key(pattern: str, **kwargs) -> str:
    """
    Build a Redis key from a pattern.

    Args:
        pattern: One of the RedisKeySchema patterns (e.g., "aiva:state:{session_id}")
        **kwargs: Values for placeholders

    Returns:
        Formatted key string

    Raises:
        ValueError: If required fields are missing from kwargs
    """
    try:
        return pattern.format(**kwargs)
    except KeyError as e:
        raise ValueError(f"Missing required field {e} for pattern '{pattern}'")


def validate_key(key: str) -> bool:
    """
    Returns True if key matches a known schema pattern.
    Strict matching — partial matches return False.
    """
    return any(p.match(key) for p in _COMPILED_PATTERNS)


def get_ttl(pattern: str) -> Optional[int]:
    """
    Returns the TTL in seconds for a given key pattern.
    Returns None for persistent keys (no TTL).
    """
    schema = RedisKeySchema()
    ttl_map = {
        schema.AIVA_WORKING_STATE:   schema.TTL_WORKING_STATE,
        schema.AIVA_TRANSCRIPT:      schema.TTL_TRANSCRIPT,
        schema.AIVA_CONTEXT_PRELOAD: schema.TTL_CONTEXT_PRELOAD,
        schema.GENESIS_STAGING:      schema.TTL_STAGING,
    }
    return ttl_map.get(pattern)
