#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""Stages 11/12: Synaptic homeostasis and deep consolidation.

Split from stage_maintenance.py for Law 7 compliance.
"""
from datetime import datetime, timezone, timedelta

from pulse.core.brain_utils import (
    LESSONS_JSONL, FAILS_JSONL, PATTERNS_JSONL,
    read_jsonl_entries,
)


def stage_synaptic_homeostasis(verbose=False):
    """Stage 11: Normalize salience to prevent inflation (Tononi & Cirelli 2014)."""
    from pulse.brain.save_writers import rewrite_jsonl
    SALIENCE_CEILING = 4.0
    SALIENCE_TARGET = 3.0
    PROTECTION_HOURS = 6
    cutoff = datetime.now(timezone.utc) - timedelta(hours=PROTECTION_HOURS)
    total_downscaled = 0
    _table_map = {
        "auto_lessons.jsonl": "lessons",
        "auto_fails.jsonl": "failures",
        "auto_patterns.jsonl": "patterns",
    }
    for jsonl_path in [LESSONS_JSONL, FAILS_JSONL, PATTERNS_JSONL]:
        if not jsonl_path.exists():
            continue
        rows = read_jsonl_entries(jsonl_path)
        if not rows:
            continue
        saliences = [r.get("salience", 2.0) for r in rows]
        mean_sal = sum(saliences) / len(saliences)
        if mean_sal <= SALIENCE_CEILING:
            if verbose:
                print(f"  [HOMEOSTASIS] {jsonl_path.name}: mean={mean_sal:.2f} (OK)")
            continue
        scale = SALIENCE_TARGET / mean_sal
        downscaled = 0
        for r in rows:
            ts = r.get("timestamp", "")
            if ts:
                try:
                    item_dt = datetime.fromisoformat(ts.replace("Z", "+00:00"))
                    if item_dt.tzinfo is None:
                        item_dt = item_dt.replace(tzinfo=timezone.utc)
                    if item_dt > cutoff:
                        continue
                except (ValueError, TypeError):
                    pass
            old_sal = r.get("salience", 2.0)
            new_sal = round(max(0.5, old_sal * scale), 2)
            if new_sal != old_sal:
                r["salience"] = new_sal
                downscaled += 1
        if downscaled > 0:
            _sqlite_ok = False
            try:
                from pulse.core.brain_db import get_conn
                table = _table_map.get(jsonl_path.name)
                if table:
                    conn = get_conn()
                    cutoff_iso = cutoff.isoformat()
                    with conn:
                        conn.execute(
                            f"UPDATE {table} SET "
                            f"salience = MAX(0.5, ROUND(salience * ?, 2)), "
                            f"updated_at = strftime('%Y-%m-%dT%H:%M:%SZ','now') "
                            f"WHERE (timestamp <= ? OR timestamp = '') "
                            f"AND validity = 'valid'",
                            (scale, cutoff_iso),
                        )
                    _sqlite_ok = True
            except Exception:
                _sqlite_ok = False
            if not _sqlite_ok:
                rewrite_jsonl(jsonl_path, rows)
            total_downscaled += downscaled
        if verbose:
            print(f"  [HOMEOSTASIS] {jsonl_path.name}: mean={mean_sal:.2f} -> ~{SALIENCE_TARGET:.1f}, "
                  f"downscaled {downscaled}/{len(rows)} (scale={scale:.3f})")
    if verbose and total_downscaled == 0:
        print("  [HOMEOSTASIS] All files within normal range")
    try:
        from pulse.core.brain_db import get_conn
        conn = get_conn()
        seven_days_ago = (datetime.now(timezone.utc) - timedelta(days=7)).isoformat()
        contracted = 0
        with conn:
            for table in ["lessons", "failures", "patterns"]:
                res = conn.execute(
                    f"UPDATE {table} SET salience = MAX(0.1, salience * 0.9) "
                    f"WHERE domain IN ("
                    f"  SELECT DISTINCT domain FROM {table} "
                    f"  GROUP BY domain HAVING MAX(timestamp) < ?"
                    f") AND validity != 'permanent'",
                    (seven_days_ago,)
                )
                contracted += res.rowcount
        if verbose and contracted > 0:
            print(f"  [FOOTPRINT] Contracted {contracted} items in dormant domains")
    except Exception:
        pass
    return {"status": "ok", "downscaled": total_downscaled}


def stage_deep_consolidation(verbose=False):
    """Stage 12: Promote permanent knowledge, archive dead knowledge."""
    try:
        from pulse.core.brain_db import get_conn
        from pulse.core import event_bus
        conn = get_conn()
        now = datetime.now(timezone.utc)
        fourteen_days_ago = (now - timedelta(days=14)).isoformat()
        thirty_days_ago = (now - timedelta(days=30)).isoformat()
        stats = {"permanent": 0, "archived": 0}
        tables = ["lessons", "failures", "patterns", "decisions", "facts"]
        with conn:
            for table in tables:
                res = conn.execute(f"""
                    UPDATE {table} SET validity = 'permanent'
                    WHERE validity = 'valid' AND confidence >= 0.7
                      AND access_count >= 5 AND timestamp <= ?
                """, (fourteen_days_ago,))
                stats["permanent"] += res.rowcount
                res = conn.execute(f"""
                    UPDATE {table} SET validity = 'archived'
                    WHERE validity = 'valid' AND confidence < 0.3
                      AND coalesce(last_accessed, timestamp) <= ?
                """, (thirty_days_ago,))
                stats["archived"] += res.rowcount
        event_bus.publish("consolidation.deep.complete", "deep_consolidation", stats)
        if verbose:
            print(f"  [DEEP] Promoted {stats['permanent']} to permanent, archived {stats['archived']}")
        return {"status": "ok", **stats}
    except ImportError:
        if verbose:
            print("  [DEEP] SQLite DAL not available")
        return {"status": "skipped"}
    except Exception as e:
        if verbose:
            print(f"  [DEEP] Error: {e}")
        return {"status": "error", "error": str(e)}

def stage_recency_bonus(verbose=False):
    """Stage N: Proactive interference recency bonus (P18-72). Newer same-domain items get confidence + 0.05."""
    try:
        from pulse.core.brain_db import get_conn
        conn = get_conn()
        one_day_ago = (datetime.now(timezone.utc) - timedelta(days=1)).isoformat()
        boosted = 0
        with conn:
            for table in ["lessons", "failures", "patterns"]:
                # P47 FIX: Only boost items once (metadata lacks _recency_boosted flag)
                res = conn.execute(
                    f"UPDATE {table} SET confidence = MIN(1.0, confidence + 0.05), "
                    f"last_reinforced = ? "
                    f"WHERE timestamp > ? AND confidence < 0.9 AND last_reinforced IS NULL",
                    (one_day_ago, one_day_ago,)
                )
                boosted += res.rowcount
        if verbose:
            print(f"  [RECENCY_BONUS] Boosted {boosted} recent items (+0.05 confidence)")
        return {"status": "ok", "boosted": boosted}
    except Exception as e:
        if verbose:
            print(f"  [RECENCY_BONUS] Error: {e}")
        return {"status": "error", "error": str(e)}
