#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""LLM-powered quality gate for brain writes.

Uses llm_router.dispatch(task_type="fast") with full cascade (Ollama -> Anthropic -> Google).
Falls back to regex-only if all providers unavailable. Cost: ~$0.001/item.
"""
import logging

log = logging.getLogger("pulse.quality.llm")

_INTENT_PROMPT = (
    "Classify this text as either GOOD or GARBAGE.\n"
    "GOOD = a real user intent, want, or actionable request.\n"
    "GARBAGE = conversation fragment, JSON artifact, markdown table, "
    "system prompt leak, or vague phrase with no actionable meaning.\n"
    "Text: \"{text}\"\n"
    "Reply with exactly one word: GOOD or GARBAGE"
)

_AP_PROMPT = (
    "Classify this text as either ACTIONABLE or GARBAGE.\n"
    "ACTIONABLE = a clear engineering rule with a directive verb "
    "(NEVER/ALWAYS/MUST/AVOID) that prevents a specific mistake.\n"
    "GARBAGE = conversation fragment, casual chat, vague observation.\n"
    "Text: \"{text}\"\n"
    "Reply with exactly one word: ACTIONABLE or GARBAGE"
)

_FACT_PROMPT = (
    "Classify this text as either DURABLE or EPHEMERAL.\n"
    "DURABLE = a fact that stays true for weeks/months.\n"
    "EPHEMERAL = temporary observation or context-dependent statement.\n"
    "Text: \"{text}\"\n"
    "Reply with exactly one word: DURABLE or EPHEMERAL"
)

_cache: dict = {}
_MAX_CACHE = 500


def _llm_classify(text, prompt_template, accept_label):
    """Classify via llm_router.dispatch (full cascade). Returns True/False/None."""
    cache_key = text[:80]
    if cache_key in _cache:
        return _cache[cache_key] == accept_label
    try:
        from pulse.core.llm_router import dispatch
        prompt = prompt_template.format(text=text[:500].replace('"', "'"))
        response = dispatch(prompt, task_type="fast", max_retries=1, temperature=0.0)
        label = response.strip().upper().split()[0] if response else ""
        if len(_cache) >= _MAX_CACHE:
            _cache.clear()
        _cache[cache_key] = label
        return label == accept_label
    except Exception as e:
        log.debug("LLM quality gate unavailable: %s", e)
        return None


def llm_gate_intent(text):
    """True if text is a real intent. Falls back to True if LLM unavailable."""
    if len(text) < 15:
        return False
    result = _llm_classify(text, _INTENT_PROMPT, "GOOD")
    return result if result is not None else True


def llm_gate_anti_pattern(text):
    """True if text is an actionable anti-pattern rule."""
    if len(text) < 20:
        return False
    result = _llm_classify(text, _AP_PROMPT, "ACTIONABLE")
    return result if result is not None else True


def llm_gate_fact(text):
    """True if text is a durable fact."""
    if len(text) < 10:
        return False
    result = _llm_classify(text, _FACT_PROMPT, "DURABLE")
    return result if result is not None else True


def llm_enhanced_quality_gate(text, table, salience=0.0, confidence=0.0):
    """Combined regex + LLM quality gate. LLM only fires for ambiguous cases."""
    from .quality import _passes_quality_gate, _GARBAGE_PATTERNS
    if _GARBAGE_PATTERNS.search(text):
        return False
    regex_pass = _passes_quality_gate(text, salience, confidence)
    if table == "intents" and regex_pass:
        return llm_gate_intent(text)
    elif table == "anti_patterns":
        return llm_gate_anti_pattern(text)
    elif table == "facts" and regex_pass:
        return llm_gate_fact(text)
    return regex_pass
