#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""
Item 129: Knowledge type routing in search (Search -- P30).

Different query types should prioritize different knowledge sources:
  "How to" queries    -> procedures first
  "Why did" queries   -> failures + decisions first
  "What is" queries   -> facts + schemas first
  "When" queries      -> episodic first
  default             -> no reordering (all sources equal priority)

Extracted to its own module to keep search_engine.py under 300 lines.
"""
import logging
import re
from typing import Dict, Callable

log = logging.getLogger("pulse.brain_search.query_routing")

# Query intent patterns -> preferred source ordering
_INTENT_PATTERNS = [
    # (regex pattern, list of source names to front-load)
    (re.compile(r"^how (to|do|can|should|would)", re.I), ["procedures", "wins"]),
    (re.compile(r"^why (did|does|would|is|was|are)", re.I), ["fails", "decisions"]),
    (re.compile(r"^what (is|are|was|were)", re.I), ["facts", "schemas"]),
    (re.compile(r"^when (did|does|will|should)", re.I), ["episodic", "decisions"]),
    (re.compile(r"^(avoid|never|don.?t|stop)", re.I), ["anti_patterns"]),
    (re.compile(r"(error|fail|broke|crash|bug|exception)", re.I), ["fails", "anti_patterns"]),
    (re.compile(r"(pattern|best practice|rule|principle)", re.I), ["patterns", "schemas"]),
]


def _detect_intent(query: str) -> list:
    """Return list of preferred source names for the given query, or empty list."""
    q = query.strip()
    for pattern, sources in _INTENT_PATTERNS:
        if pattern.search(q):
            return sources
    return []


def boost_sources_by_intent(query: str, search_fns: Dict[str, Callable]) -> Dict[str, Callable]:
    """Reorder search_fns dict so that intent-matched sources appear first.

    Python 3.7+ dicts maintain insertion order. This means the parallel executor
    will submit preferred sources first, improving result latency for common
    query intents.

    Args:
        query: The search query string.
        search_fns: Dict of {source_name: search_function}.

    Returns:
        Reordered dict (fail-open: returns original if any error).
    """
    try:
        preferred = _detect_intent(query)
        if not preferred:
            return search_fns  # No reordering needed

        # Build reordered dict: preferred sources first, then the rest
        reordered: Dict[str, Callable] = {}
        for src in preferred:
            if src in search_fns:
                reordered[src] = search_fns[src]
        for src, fn in search_fns.items():
            if src not in reordered:
                reordered[src] = fn

        log.debug("Query intent routing: preferred=%s for query=%r", preferred, query[:60])
        return reordered
    except Exception as e:
        log.debug("boost_sources_by_intent failed: %s", e)
        return search_fns  # fail-open
