#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""
Private Brain Synthesis: Consolidate private learnings into patterns.

Scans Hippocampus/Private/ for JSONL lessons, JSON evidence.
Extracts recurring themes and writes synthesized patterns to
Hippocampus/Private/private_patterns.json.

Run manually or scheduled by orchestrator (every 24h).
Dependencies: Python stdlib only (Law 4)
"""

import json
import re
from collections import Counter
from datetime import datetime, timezone
from pathlib import Path

from pulse.core.brain_utils import HIPPOCAMPUS_DIR, PRIVATE_JSONL, read_jsonl_entries

PRIVATE_DIR = HIPPOCAMPUS_DIR / "Private"
EVIDENCE_FILE = PRIVATE_DIR / "private_evidence.json"
PATTERNS_FILE = PRIVATE_DIR / "private_patterns.json"

# Words to ignore when finding themes
_STOP_WORDS = frozenset({
    "the", "a", "an", "is", "was", "are", "were", "be", "been",
    "have", "has", "had", "do", "does", "did", "will", "would",
    "could", "should", "may", "might", "can", "shall", "to", "of",
    "in", "for", "on", "with", "at", "by", "from", "as", "into",
    "through", "during", "before", "after", "above", "below",
    "between", "under", "again", "further", "then", "once", "that",
    "this", "these", "those", "it", "its", "not", "no", "nor",
    "but", "or", "and", "if", "so", "than", "too", "very",
    "just", "about", "also", "more", "some", "any", "each",
    "which", "who", "what", "when", "where", "how", "why",
    "all", "both", "other", "such", "only",
})


def _extract_themes(texts: list[str], min_count: int = 2) -> list[tuple[str, int]]:
    """Find recurring 2-3 word phrases across texts."""
    phrase_counts = Counter()
    for text in texts:
        words = [w.lower().strip(".,;:!?()\"'") for w in text.split()
                 if len(w) > 3 and w.lower() not in _STOP_WORDS]
        for i in range(len(words) - 1):
            phrase = f"{words[i]} {words[i+1]}"
            phrase_counts[phrase] += 1
        for i in range(len(words) - 2):
            phrase = f"{words[i]} {words[i+1]} {words[i+2]}"
            phrase_counts[phrase] += 1

    return [(phrase, count) for phrase, count in phrase_counts.most_common(20)
            if count >= min_count]


def _cluster_by_theme(texts: list[str], themes: list[tuple[str, int]]) -> dict[str, list[str]]:
    """Group texts by which theme they match."""
    clusters = {}
    assigned = set()
    for phrase, _ in themes:
        cluster = []
        for i, text in enumerate(texts):
            if i in assigned:
                continue
            if phrase in text.lower():
                cluster.append(text)
                assigned.add(i)
        if cluster:
            clusters[phrase] = cluster
    return clusters


def synthesize() -> dict:
    """
    Main synthesis: read private JSONL lessons + JSON evidence, find patterns,
    write synthesized patterns to private_patterns.json.
    """
    PRIVATE_DIR.mkdir(parents=True, exist_ok=True)
    all_texts = []

    # 1. Read private lessons (JSONL)
    rows = read_jsonl_entries(PRIVATE_JSONL)
    for row in rows:
        text = (row.get("content") or row.get("title", ""))
        if text and len(text) > 20:
            all_texts.append(text[:300])

    # 2. Read private evidence (JSON)
    if EVIDENCE_FILE.exists():
        try:
            items = json.loads(EVIDENCE_FILE.read_text(encoding="utf-8"))
            if isinstance(items, list):
                for item in items:
                    text = item.get("description", "") or item.get("text", "")
                    if text and len(text) > 20:
                        all_texts.append(text[:300])
        except (json.JSONDecodeError, Exception):
            pass

    results = {
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "texts_analyzed": len(all_texts),
        "themes_found": 0,
        "patterns_written": 0,
    }

    if len(all_texts) < 2:
        return results

    # 3. Find recurring themes
    themes = _extract_themes(all_texts)
    results["themes_found"] = len(themes)

    if not themes:
        return results

    # 4. Cluster texts by theme
    clusters = _cluster_by_theme(all_texts, themes)

    # 5. Write synthesized patterns as JSON
    now = datetime.now(timezone.utc)
    output = {
        "type": "private-synthesis",
        "last_updated": now.isoformat(),
        "patterns": [],
    }

    for theme, texts in clusters.items():
        output["patterns"].append({
            "theme": theme.title(),
            "frequency": len(texts),
            "examples": [t[:200] for t in texts[:3]],
        })
        results["patterns_written"] += 1

    PATTERNS_FILE.write_text(json.dumps(output, indent=2, ensure_ascii=False), encoding="utf-8")
    return results


if __name__ == "__main__":
    result = synthesize()
    print(json.dumps(result, indent=2))
