#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""Knowledge gap mapping — Item 166.

  - Item 166: Knowledge gap mapping (Metacognition)

Identify domains where the brain has fewer than 5 items.
These gaps should trigger EXPLORE tasks.
"""
import logging
from typing import Dict, Any, List

log = logging.getLogger("pulse.brain.knowledge_gap_map")

_GAP_THRESHOLD = 5   # domains with fewer items than this are gaps


def get_knowledge_gaps() -> Dict[str, Any]:
    """Find domains where the brain has fewer than 5 items.

    Returns:
        {
            gaps: [{domain, item_count}],
            gap_count: int,
            warning: str or None,
        }
    Fails open (returns no gaps) on any error.
    """
    result: Dict[str, Any] = {
        "gaps": [],
        "gap_count": 0,
        "warning": None,
    }
    try:
        from pulse.core.brain_db import get_conn
        conn = get_conn()

        domain_counts: Dict[str, int] = {}
        for tbl in ("lessons", "failures", "patterns", "facts"):
            try:
                rows = conn.execute(
                    f"SELECT domain, COUNT(*) FROM {tbl} "
                    f"WHERE validity = 'valid' AND domain IS NOT NULL AND domain != '' "
                    f"GROUP BY domain"
                ).fetchall()
                for row in rows:
                    d = str(row[0])
                    n = int(row[1] or 0)
                    domain_counts[d] = domain_counts.get(d, 0) + n
            except Exception:
                pass

        gaps = [
            {"domain": d, "item_count": n}
            for d, n in domain_counts.items()
            if n < _GAP_THRESHOLD
        ]
        gaps.sort(key=lambda x: x["item_count"])

        warning = None
        if gaps:
            domains_str = ", ".join(g["domain"] for g in gaps[:5])
            warning = (
                f"!! KNOWLEDGE GAPS: {len(gaps)} domains have <{_GAP_THRESHOLD} items "
                f"({domains_str}{'...' if len(gaps) > 5 else ''}) — recommend EXPLORE tasks"
            )

        result.update({
            "gaps": gaps,
            "gap_count": len(gaps),
            "warning": warning,
        })

    except Exception as exc:
        log.debug("get_knowledge_gaps failed: %s", exc)

    return result
