# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""
Dimension B: Source Credibility / Agent Trust.

Public: extract_belief_state, compute_trust, recompute_all, get_trust
Storage: state/agent_trust.json

Modularized: trust_io.py (I/O), trust_metrics.py (metric computation).
"""
import json
from pulse.core.brain_utils import STATE_DIR, now_iso  # noqa: F401 re-exported for patching
from pulse.admin.audit.trust_io import (  # noqa: F401
    TRUST_FILE, _load_trust, _save_trust, _bootstrap_trust, _collect_known_agents,
)
from pulse.admin.audit.trust_metrics import (  # noqa: F401
    _compute_accuracy, _compute_prediction_accuracy, _compute_contradiction_rate,
    _compute_longevity, _find_first_seen,
)


def extract_belief_state(agent_name, verbose=False):
    """Parse agent recent outputs to extract core assumptions (Theory of Mind model)."""
    try:
        from pulse.core.llm_router import dispatch
    except ImportError:
        return []
    sessions_dir = STATE_DIR / "worker_sessions"
    if not sessions_dir.exists():
        return []
    agent_sessions = []
    for sf in sessions_dir.glob("*.json"):
        try:
            with open(sf, "r", encoding="utf-8") as f:
                sess = json.load(f)
                if (agent_name.lower() in sess.get("worker_id", "").lower()
                        or agent_name.lower() in sess.get("model", "").lower()):
                    agent_sessions.append(sess)
        except Exception:
            continue
    if not agent_sessions:
        return []
    agent_sessions.sort(key=lambda x: x.get("completed_at", ""), reverse=True)
    reasoning = []
    for sess in agent_sessions[:3]:
        for e in sess.get("events", []):
            if e.get("type") == "reasoning":
                reasoning.append(e.get("content", ""))
    if not reasoning:
        return []
    trace_text = (" --- ").join(reasoning)[:4000]
    prompt = (
        "Analyze reasoning traces from agent " + repr(agent_name) + ". "
        "Extract 3 core technical assumptions (BeliefsState). "
        "Return JSON: {beliefs: [belief1, belief2, belief3]}. "
        "Traces: " + trace_text
    )
    res = dispatch("standard", prompt)
    if res and isinstance(res.get("beliefs"), list):
        beliefs = res["beliefs"]
        data = _load_trust()
        if agent_name not in data.setdefault("agents", {}):
            data["agents"][agent_name] = {"trust_score": 0.1, "tier": "untested"}
        data["agents"][agent_name]["beliefs"] = beliefs
        data["agents"][agent_name]["last_beliefs_extracted"] = now_iso()
        _save_trust(data)
        return beliefs
    return []


def compute_trust(agent_name):
    """Compute trust score: 0.4*accuracy + 0.3*prediction + 0.2*contradiction_inv + 0.1*longevity."""
    contributions, survived, accuracy_rate = _compute_accuracy(agent_name)
    if contributions < 5:
        bootstrap_score, tier = _bootstrap_trust(agent_name)
        return {
            "trust_score": bootstrap_score, "contributions": contributions,
            "survived_consolidation": survived, "contradictions_involved": 0,
            "predictions_correct": 0, "predictions_total": 0, "first_seen": "",
            "last_seen": now_iso(), "tier": tier, "accuracy_rate": accuracy_rate,
            "last_computed": now_iso(),
        }
    pred_correct, pred_total, pred_accuracy = _compute_prediction_accuracy(agent_name)
    contradictions, _ = _compute_contradiction_rate(agent_name)
    contradiction_inv = max(0.0, 1.0 - (contradictions / max(contributions, 1)))
    existing = _load_trust()
    agent_data = existing.get("agents", {}).get(agent_name, {})
    first_seen = agent_data.get("first_seen", "") or _find_first_seen(agent_name)
    longevity = _compute_longevity(agent_name, first_seen)
    trust = round(min(1.0, max(0.0,
        0.4 * accuracy_rate + 0.3 * pred_accuracy
        + 0.2 * contradiction_inv + 0.1 * longevity)), 4)
    _, tier = _bootstrap_trust(agent_name)
    return {
        "trust_score": trust, "contributions": contributions,
        "survived_consolidation": survived, "contradictions_involved": contradictions,
        "predictions_correct": pred_correct, "predictions_total": pred_total,
        "first_seen": first_seen, "last_seen": now_iso(), "tier": tier,
        "accuracy_rate": accuracy_rate, "last_computed": now_iso(),
    }


def recompute_all(verbose=False):
    """Recompute trust for all known agents, save to state file."""
    agents = _collect_known_agents()
    data = _load_trust()
    agents_dict = data.get("agents", {})
    for agent_name in agents:
        record = compute_trust(agent_name)
        agents_dict[agent_name] = record
        if verbose:
            print("  [TRUST] " + agent_name + ": " + str(record["trust_score"]))
    data["agents"] = agents_dict
    data["last_recomputed"] = now_iso()
    _save_trust(data)
    return data


def get_trust(agent_name):
    """Get cached trust score. Bootstrap default for unknown agents."""
    data = _load_trust()
    agent_data = data.get("agents", {}).get(agent_name, {})
    if agent_data and agent_data.get("trust_score") is not None:
        return agent_data["trust_score"]
    name_lower = agent_name.lower()
    for key, val in data.get("agents", {}).items():
        if name_lower in key.lower() or key.lower() in name_lower:
            score = val.get("trust_score")
            if score is not None:
                return score
    bootstrap_score, _ = _bootstrap_trust(agent_name)
    return bootstrap_score
