#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""
Phase 2: Metacognitive Control — Domain competence drives search behavior.

When the brain knows it's weak in a domain (blind_spot/novice), it:
- Searches deeper (more results per source)
- Flags results for extra caution
- Optionally generates a learning task to fill the gap

When the brain is expert in a domain:
- Searches efficiently (fewer results, higher confidence gate)
- Trusts results more

Usage:
    from pulse.brain.metacognition.metacognitive_control import get_search_directive
    directive = get_search_directive("fix the database migration")
    results = brain_search(query, max_per_source=directive.max_per_source, ...)
"""
import logging
from dataclasses import dataclass

log = logging.getLogger("pulse.metacognitive_control")

# Domain keyword mapping — infer domain from query text
_DOMAIN_KEYWORDS: dict[str, list[str]] = {
    "security": ["security", "auth", "encrypt", "token", "xss", "injection", "csrf"],
    "architecture": ["architect", "design", "refactor", "pattern", "structure", "module"],
    "testing": ["test", "assert", "mock", "fixture", "coverage", "pytest", "unittest"],
    "database": ["database", "sql", "sqlite", "migration", "schema", "query", "table"],
    "api": ["api", "endpoint", "rest", "graphql", "route", "request", "response"],
    "deployment": ["deploy", "docker", "ci", "cd", "pipeline", "build", "release"],
    "brain": ["brain", "knowledge", "hippocampus", "consolidation", "search", "memory"],
    "swarm": ["swarm", "agent", "worker", "task", "dispatch", "orchestrat"],
    "frontend": ["react", "css", "html", "component", "render", "ui", "ux", "tailwind"],
}


@dataclass
class SearchDirective:
    """Controls search behavior based on domain competence."""
    domain: str
    competence_level: str  # blind_spot, novice, competent, expert
    max_per_source: int    # How many results per source
    confidence_gate: float # Min confidence to include result
    search_exhaustive: bool # Whether to force full scan (skip index fast-path)
    generate_learning_task: bool  # Should we post a learning task?


def infer_domain(query: str) -> str:
    """Infer domain from query keywords. Returns best match or 'general'."""
    ql = query.lower()
    best_domain = "general"
    best_score = 0
    for domain, keywords in _DOMAIN_KEYWORDS.items():
        score = sum(1 for kw in keywords if kw in ql)
        if score > best_score:
            best_score = score
            best_domain = domain
    return best_domain


def get_search_directive(query: str) -> SearchDirective:
    """Compute metacognitive search directive from query + metamemory.

    Policy:
      blind_spot → exhaustive search, low confidence gate, generate learning task
      novice     → extended search (5/source), low gate
      competent  → normal search (3/source), normal gate
      expert     → efficient search (3/source), higher gate
    """
    domain = infer_domain(query)
    competence = "competent"  # Default

    try:
        from pulse.brain.metacognition.metamemory import get_metamemory
        meta = get_metamemory()
        if domain in meta:
            competence = meta[domain].get("competence_level", "competent")
    except Exception:
        pass

    if competence == "blind_spot":
        return SearchDirective(
            domain=domain, competence_level=competence,
            max_per_source=5, confidence_gate=0.2,
            search_exhaustive=True, generate_learning_task=True,
        )
    elif competence == "novice":
        return SearchDirective(
            domain=domain, competence_level=competence,
            max_per_source=5, confidence_gate=0.3,
            search_exhaustive=False, generate_learning_task=False,
        )
    elif competence == "expert":
        return SearchDirective(
            domain=domain, competence_level=competence,
            max_per_source=3, confidence_gate=0.5,
            search_exhaustive=False, generate_learning_task=False,
        )
    else:  # competent
        return SearchDirective(
            domain=domain, competence_level=competence,
            max_per_source=3, confidence_gate=0.4,
            search_exhaustive=False, generate_learning_task=False,
        )
