#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""Brain Compliance Tracker — scores and persists per-agent brain usage.

E2: Tracks brain queries vs actions ratio per agent.
E5: Infers skill usage from session context when agents don't report explicitly.
"""
from __future__ import annotations

import json
import logging
from datetime import datetime, timezone
from pathlib import Path

from pulse.core.pii_filter import redact_pii

ROOT_DIR = Path(__file__).resolve().parent.parent.parent
STATE_DIR = ROOT_DIR / "state"
COMPLIANCE_FILE = STATE_DIR / "brain_compliance.json"
FAILS_FILE = ROOT_DIR / "Hippocampus" / "Failures" / "auto_fails.md"


# ── E2: Brain Compliance Scoring ──────────────────────────────────

def update_compliance(agent_name: str, brain_queries: int, actions_taken: int) -> float:
    """Score brain compliance and persist. Returns score (0.0–1.0).

    score = brain_queries / max(1, actions_taken)
    Score < 0.5 auto-writes a failure flag for the agent.
    Maintains rolling 10-session average per agent.
    """
    score = min(1.0, brain_queries / max(1, actions_taken))
    now = datetime.now(timezone.utc).isoformat()

    try:
        data = json.loads(COMPLIANCE_FILE.read_text(encoding="utf-8")) if COMPLIANCE_FILE.exists() else {}
    except Exception:
        data = {}

    entry = data.get(agent_name, {"scores": [], "last_updated": ""})
    scores = entry.get("scores", [])
    scores.append(score)
    scores = scores[-10:]  # Rolling 10-session window
    avg = sum(scores) / len(scores)

    data[agent_name] = {"scores": scores, "avg": round(avg, 3), "last_updated": now}
    STATE_DIR.mkdir(parents=True, exist_ok=True)
    COMPLIANCE_FILE.write_text(json.dumps(data, indent=2), encoding="utf-8")

    # Auto-flag low compliance
    if score < 0.5 and FAILS_FILE.exists():
        try:
            safe_name = redact_pii(agent_name)
            with open(FAILS_FILE, "a", encoding="utf-8") as f:
                f.write(f"\n## Low brain compliance: {safe_name} ({score:.0%})\n")
                f.write(f"**Agent:** {safe_name}\n")
                f.write(f"**Date:** {now[:10]}\n")
                f.write(f"**Confidence:** 0.7\n")
                f.write(f"Brain queries: {brain_queries}, actions: {actions_taken}. "
                        f"Agent is not consulting the brain enough.\n\n")
        except Exception:
            logging.debug("Suppressed exception in compliance_tracker", exc_info=True)

    return score


def get_compliance_summary() -> dict:
    """Per-agent compliance summary for boot briefing."""
    try:
        data = json.loads(COMPLIANCE_FILE.read_text(encoding="utf-8")) if COMPLIANCE_FILE.exists() else {}
    except Exception:
        return {}
    return {agent: {"avg": info.get("avg", 0), "sessions": len(info.get("scores", []))}
            for agent, info in data.items()}


# ── E5: Skill Usage Inference ─────────────────────────────────────

_SKILL_KEYWORDS = {
    "refactor": "REFACTOR_DRUID", "rename": "REFACTOR_DRUID",
    "test": "TESTING_SHIELD", "pytest": "TESTING_SHIELD", "unittest": "TESTING_SHIELD",
    "security": "SECURITY_SENTINEL", "vulnerability": "SECURITY_SENTINEL",
    "api": "API_ARCHITECT", "endpoint": "API_ARCHITECT",
    "deploy": "DEPLOY_CAPTAIN", "docker": "DEPLOY_CAPTAIN",
    "database": "DATA_SAGE", "sql": "DATA_SAGE", "migration": "DATA_SAGE",
    "debug": "DEBUG_DETECTIVE", "traceback": "DEBUG_DETECTIVE",
    "performance": "PERF_OPTIMIZER", "slow": "PERF_OPTIMIZER",
    "documentation": "DOC_WRITER", "readme": "DOC_WRITER",
}


def infer_skills_from_session(learnings: list, failures: list,
                              files_touched: list) -> list[str]:
    """Infer which skills were likely used from session context."""
    combined = " ".join(
        (learnings or []) + (failures or []) + (files_touched or [])
    ).lower()
    if not combined.strip():
        return []
    found = set()
    for keyword, skill in _SKILL_KEYWORDS.items():
        if keyword in combined:
            found.add(skill)
    return sorted(found)