#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
# See LICENSE file for details.
"""
Consolidation Stages Runner: Executes all 22 consolidation stages in sequence.

Extracted from consolidation_daemon.py to keep both files under 300 lines.
Called by run_consolidation() in consolidation_daemon.py.
"""
import time
from pathlib import Path

from pulse.core.brain_utils import HIPPOCAMPUS_DIR, save_json, now_iso as _now_iso
from pulse.daemons.consolidation.consolidation_stages import (
    stage_dedup,
    stage_pattern_mining,
    stage_schema_promotion,
    stage_schema_promotion_from_sequences,
    register_discovered_procedures,
    stage_ltd_decay,
    stage_graph_update,
    stage_reconsolidation,
    stage_cross_domain_transfer,
    stage_promote_to_patterns,
    stage_metacognitive_audit,
    stage_hierarchical_prune,
    stage_truth_verification,
    stage_recency_bonus,
    stage_schema_distortion_audit,
    stage_episodic_graduation,
)


def run_early_stages(verbose: bool = False) -> dict:
    """Run consolidation stages 1-10c. Returns result dict for run_late_stages."""
    start = time.time()

    # Stage 1: Dedup
    print("[CONSOLIDATION] Stage 1: Deduplication")
    dedup_result = stage_dedup(verbose=verbose)

    # Stage 1b: EchoRefine (D19 — cross-ref golden paths + constraints)
    print("[CONSOLIDATION] Stage 1b: EchoRefine Synthesis")
    try:
        from pulse.daemons.synthesis.resonance.echo_refine import run_once as echorefine_once
        echo_result = echorefine_once(verbose=verbose)
        if verbose:
            print(f"  [ECHOREFINE] {echo_result.get('entries', 0)} scanned, "
                  f"{echo_result.get('golden_aligned', 0)} aligned, "
                  f"{echo_result.get('constraint_conflicts', 0)} conflicts")
    except Exception as e:
        if verbose:
            print(f"  [ECHOREFINE] Skipped: {e}")

    # Stage 2: Pattern Mining
    print("[CONSOLIDATION] Stage 2: Pattern Mining")
    mining_result = stage_pattern_mining(verbose=verbose)

    # Stage 2e2: Episodic Graduation (promote episodic memories to semantic)
    try:
        episodic_grad_result = stage_episodic_graduation(verbose=verbose)
    except Exception as e:
        episodic_grad_result = {"status": "error", "error": str(e)}

    # Stage 2b: Register discovered procedures (Fix 4)
    sequences = mining_result.get("sequences", [])
    print("[CONSOLIDATION] Stage 2b: Register Discovered Procedures")
    proc_count = register_discovered_procedures(sequences, verbose=verbose)

    # Verify procedure persistence
    proc_log = HIPPOCAMPUS_DIR / "Evidence" / "Metrics" / "procedural_log.json"
    if proc_log.exists():
        from pulse.core.brain_utils import load_json
        proc_data = load_json(proc_log)
        actual_count = len(proc_data) if isinstance(proc_data, list) else 0
        if verbose:
            print(f"  [PROCEDURES] Verified: {actual_count} procedures on disk")
    elif proc_count > 0:
        print(f"  [PROCEDURES] WARNING: registered {proc_count} but procedural_log.json missing!")

    # Stage 2c: LTD Decay (flag unretrieved old items)
    print("[CONSOLIDATION] Stage 2c: LTD Decay")
    ltd_result = stage_ltd_decay(verbose=verbose)

    # Stage 2d: Auto-reconsolidation (U6: merge similar entries)
    print("[CONSOLIDATION] Stage 2d: Reconsolidation")
    recon_result = stage_reconsolidation(verbose=verbose)

    # Stage 2e: Cross-Domain Transfer Detection
    print("[CONSOLIDATION] Stage 2e: Cross-Domain Transfer")
    transfer_result = stage_cross_domain_transfer(verbose=verbose)

    # Stage 2f: Cross-Region Mining
    print("[CONSOLIDATION] Stage 2f: Cross-Region Mining")
    try:
        from pulse.daemons.consolidation.consolidation_stages import stage_2f_cross_region_mining
        cross_region_result = stage_2f_cross_region_mining(verbose=verbose)
    except Exception as e:
        cross_region_result = {"status": "error", "error": str(e)}

    # Stage 3: Schema Promotion (cross-patterns)
    # Sacred Boundary #7: approval gate on brain self-modification
    print("[CONSOLIDATION] Stage 3: Schema Promotion")
    cross_patterns = mining_result.get("cross_patterns", [])
    try:
        from pulse.daemons.consolidation.approval_gate import check_approval
        approved_cp, blocked_cp = check_approval("schema_promotion", cross_patterns)
        if blocked_cp and verbose:
            print(f"  [APPROVAL] {len(blocked_cp)} schemas pending human review")
    except Exception:
        approved_cp = cross_patterns
    schema_result = stage_schema_promotion(approved_cp, verbose=verbose)

    # Stage 3b: Sequence -> Schema Promotion (Fix 2)
    print("[CONSOLIDATION] Stage 3b: Sequence Schema Promotion")
    seq_schema_result = stage_schema_promotion_from_sequences(sequences, verbose=verbose)

    # Stage 3c: Micro-Pattern Promotion
    print("[CONSOLIDATION] Stage 3c: Micro-Pattern Promotion")
    try:
        from pulse.daemons.consolidation.consolidation_stages import stage_3c_micro_pattern_promotion
        micro_pattern_result = stage_3c_micro_pattern_promotion(verbose=verbose)
    except Exception as e:
        micro_pattern_result = {"status": "error", "error": str(e)}

    # Stage 3d: Meta-Schema Build (Level 2 abstraction — clusters of schemas)
    print("[CONSOLIDATION] Stage 3d: Meta-Schema Build")
    try:
        from pulse.brain.metacognition.meta_schemas import build_meta_schemas
        meta_schema_result = build_meta_schemas(verbose=verbose)
        if verbose:
            print(f"  [META-SCHEMAS] {meta_schema_result.get('meta_schemas', 0)} meta-schemas, "
                  f"{meta_schema_result.get('principles', 0)} principles")
    except Exception as e:
        meta_schema_result = {"status": "error", "error": str(e)}

    # Stage 4: Knowledge Graph Update (Phase 7)
    print("[CONSOLIDATION] Stage 4: Knowledge Graph Update")
    graph_result = stage_graph_update(verbose=verbose)

    # Stage 4b: Promote high-confidence lessons/failures to patterns
    # Sacred Boundary #7: approval gate on pattern promotion
    print("[CONSOLIDATION] Stage 4b: Promote to Patterns")
    try:
        promote_result = stage_promote_to_patterns(verbose=verbose)
    except Exception as e:
        promote_result = {"status": "error", "error": str(e)}
    try:
        from pulse.daemons.consolidation.approval_gate import check_approval
        promoted_items = promote_result.get("promoted", [])
        if isinstance(promoted_items, list) and len(promoted_items) > 0:
            approved_p, blocked_p = check_approval("promote_to_patterns", promoted_items)
            if blocked_p and verbose:
                print(f"  [APPROVAL] {len(blocked_p)} pattern promotions pending human review")
    except Exception:
        pass

    # Stage 4c: Abstraction (generalize recurring patterns)
    print("[CONSOLIDATION] Stage 4c: Abstraction")
    try:
        from pulse.daemons.consolidation.consolidation_stages import stage_4c_abstraction
        abstraction_result = stage_4c_abstraction(verbose=verbose)
    except Exception as e:
        abstraction_result = {"status": "error", "error": str(e)}

    # Stage 5: Metacognitive Audit (U9: brain quality check)
    print("[CONSOLIDATION] Stage 5: Metacognitive Audit")
    meta_result = stage_metacognitive_audit(verbose=verbose)

    # Stage 6: Hierarchical Prune (Miller's Law — Q8 Neural Hardening)
    print("[CONSOLIDATION] Stage 6: Hierarchical Prune")
    prune_result = stage_hierarchical_prune(verbose=verbose)

    # Stage 7: Brain Health Check (silent watchdog — detects pipeline breaks)
    print("[CONSOLIDATION] Stage 7: Brain Health Check")
    try:
        from pulse.admin.audit.brain_health import check_brain_health
        health_result = check_brain_health(verbose=verbose)
        if health_result.get("alerts"):
            for alert in health_result["alerts"]:
                print(f"  [HEALTH ALERT] {alert}")
    except Exception as e:
        health_result = {"status": "error", "error": str(e)}

    # Stage 8: Truth Verification (Dimension A — contradiction detection + penalties)
    print("[CONSOLIDATION] Stage 8: Truth Verification")
    try:
        truth_result = stage_truth_verification(verbose=verbose)
    except Exception as e:
        truth_result = {"status": "error", "error": str(e)}

    # Stage 8b: Schema Distortion Audit (detect corrupted/drifted schemas)
    try:
        schema_audit_result = stage_schema_distortion_audit(verbose=verbose)
    except Exception as e:
        schema_audit_result = {"status": "error", "error": str(e)}

    # Stage 9: Decision Consolidation (merge/deduplicate decision entries)
    print("[CONSOLIDATION] Stage 9: Decision Consolidation")
    try:
        from pulse.daemons.consolidation.consolidation_decisions import stage_decision_consolidation
        decision_result = stage_decision_consolidation(verbose=verbose)
    except Exception as e:
        decision_result = {"status": "error", "error": str(e)}

    # Stage 6b: Rebuild search index (hybrid fast-path for brain_search)
    print("[CONSOLIDATION] Stage 6b: Rebuild Search Index")
    try:
        from pulse.brain.index.search_index import build_index
        index_result = build_index(verbose=verbose)
    except Exception as e:
        index_result = {"status": "error", "error": str(e)}

    # Stage 10: Metamemory (domain confidence map refresh)
    print("[CONSOLIDATION] Stage 10: Metamemory")
    try:
        from pulse.daemons.consolidation.consolidation_stages import stage_10_metamemory
        metamemory_result = stage_10_metamemory(verbose=verbose)
    except Exception as e:
        metamemory_result = {"status": "error", "error": str(e)}

    # Stage 10b: Synaptic Homeostasis (Tononi & Cirelli 2014)
    print("[CONSOLIDATION] Stage 10b: Synaptic Homeostasis")
    try:
        from pulse.daemons.consolidation.consolidation_stages import stage_synaptic_homeostasis
        homeostasis_result = stage_synaptic_homeostasis(verbose=verbose)
    except Exception as e:
        homeostasis_result = {"status": "error", "error": str(e)}

    # Stage 10c: Recency Bonus (boost recently-retrieved items)
    try:
        recency_result = stage_recency_bonus(verbose=verbose)
    except Exception as e:
        recency_result = {"status": "error", "error": str(e)}
    return {
        "start": start,
        "dedup_result": dedup_result,
        "mining_result": mining_result,
        "sequences": sequences,
        "cross_patterns": cross_patterns,
        "proc_count": proc_count,
        "episodic_grad_result": episodic_grad_result,
        "ltd_result": ltd_result,
        "recon_result": recon_result,
        "transfer_result": transfer_result,
        "cross_region_result": cross_region_result,
        "schema_result": schema_result,
        "seq_schema_result": seq_schema_result,
        "micro_pattern_result": micro_pattern_result,
        "meta_schema_result": meta_schema_result,
        "graph_result": graph_result,
        "abstraction_result": abstraction_result if "abstraction_result" in locals() else None,
        "promote_result": promote_result,
        "meta_result": meta_result,
        "prune_result": prune_result,
        "health_result": health_result,
        "truth_result": truth_result,
        "schema_audit_result": schema_audit_result,
        "decision_result": decision_result,
        "index_result": index_result,
        "metamemory_result": metamemory_result,
        "homeostasis_result": homeostasis_result,
        "recency_result": recency_result,
    }
