#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""
Search Source: Declarative Facts (Symposium P0)

Searches Hippocampus/Knowledge/auto_facts.json for matching facts.
Returns salience-scored results matching the brain_search contract.

Dependencies: Python stdlib + brain_utils (Law 4)
"""

from pulse.core.brain_utils import FACTS_FILE
from pulse.core.brain_analysis import text_similarity


def search_facts(query: str, config: dict = None) -> list:
    """
    Search auto_facts.json for facts matching query.

    Matches by: entity name, fact text similarity, fact_type, domain.
    Returns list of hit dicts compatible with brain_search format.
    """
    if not FACTS_FILE.exists():
        return []

    import json
    try:
        facts = json.loads(FACTS_FILE.read_text(encoding="utf-8"))
        if not isinstance(facts, list):
            return []
    except (json.JSONDecodeError, OSError):
        return []

    query_lower = query.lower().strip()
    if not query_lower:
        return []

    hits = []
    for fact in facts:
        fact_text = fact.get("fact", "")
        entities = fact.get("entities", [])
        fact_type = fact.get("fact_type", "")
        domain = fact.get("domain", "general")

        score = 0.0

        # Entity match (strongest signal)
        for entity in entities:
            if entity.lower() in query_lower or query_lower in entity.lower():
                score += 3.0
                break

        # Text similarity
        sim = text_similarity(query_lower[:80], fact_text[:80].lower())
        score += sim * 2.0

        # Domain match
        if domain in query_lower:
            score += 0.5

        # Fact type keyword match
        if fact_type in query_lower:
            score += 0.3

        # Keyword overlap (simple word intersection)
        query_words = set(query_lower.split())
        fact_words = set(fact_text.lower().split())
        overlap = len(query_words & fact_words)
        if overlap >= 2:
            score += overlap * 0.3

        if score < 0.5:
            continue

        # Apply salience boost (facts are reference knowledge = high value)
        salience = fact.get("salience", 2.0) * 1.5
        confidence = fact.get("confidence", 0.7)

        hits.append({
            "text": fact_text[:200],
            "title": f"[{fact_type.upper()}] {fact_text[:80]}",
            "salience": round(salience, 3),
            "confidence": confidence,
            "source": "facts",
            "domain": domain,
            "temporal": fact.get("temporal", "current"),
            "entities": entities,
        })

    # Sort by score (implicit via salience), return top results
    hits.sort(key=lambda h: h["salience"], reverse=True)
    return hits[:10]
