#!/usr/bin/env python3
"""
Test MCP runtime tools with proper salience understanding.

This demonstrates how to use MCP tools correctly:
- Check salience/yearning state
- Only call runtime_step when appropriate
- Monitor controller decisions
- Track adaptive learning
"""

import sys
from pathlib import Path

# Add repo to path
sys.path.insert(0, str(Path(__file__).parent))


def test_mcp_with_salience_awareness():
    """
    Test MCP tools while respecting the salience architecture.
    
    Unlike our previous approach (5000 unconditional steps),
    this checks salience before deciding to train.
    """
    
    print("="*80)
    print("MCP TOOLS WITH SALIENCE AWARENESS")
    print("="*80)
    print()
    
    # Import MCP tools (these would normally come from the MCP server)
    from runtime.mcp_server import MonikaRuntimeServer
    
    # Create server instance
    server = MonikaRuntimeServer()
    
    # Example training data
    examples = [
        "Hello I am MONIKA learning to speak",
        "I understand patterns through experience",
        "Thank you for your patience teaching me",
        "Language emerges from repeated interaction",
        "Communication enables shared understanding",
    ]
    
    print("Training with salience monitoring:")
    print()
    
    for idx, text in enumerate(examples, 1):
        print(f"--- Example {idx}: '{text[:40]}...' ---")
        
        # 1. Check current yearning/salience state
        yearning = server._handle_yearning_state()
        
        # Example: Check if SASS action has high desire
        sass_desire = yearning.get('depth=0|op=SASS|patch=NONE', {}).get('desire', 0)
        sass_novelty = yearning.get('depth=0|op=SASS|patch=NONE', {}).get('affinity', 0)
        
        print(f"  Yearning state:")
        print(f"    SASS desire: {sass_desire:.3f}")
        print(f"    SASS affinity: {sass_novelty:.3f}")
        
        # 2. Decide whether to train based on salience
        # (In practice, the runtime/controller does this automatically,
        #  but this shows the principle)
        
        should_train = sass_desire > 0.5  # Example threshold
        
        if should_train:
            print(f"  → HIGH desire, proceeding with runtime_step")
            
            # 3. Call runtime_step (full salience loop)
            result = server._handle_runtime_step(text)
            
            print(f"  → Step: {result['step']}")
            print(f"  → Meta: {result['meta_report']}")
            print()
        else:
            print(f"  → LOW desire, skipping (salience too low)")
            print(f"  → This is CORRECT behavior - not every input should train!")
            print()
    
    # Get final training metrics
    metrics = server._handle_training_metrics()
    print("="*80)
    print("FINAL METRICS")
    print("="*80)
    print(f"Steps: {metrics['step']}")
    print(f"Vocab: {metrics['vocab_size']}")
    print(f"Loss: {metrics['latest_loss']:.4f}")
    print()
    
    # Test generation
    print("="*80)
    print("GENERATION TEST")
    print("="*80)
    
    gen_result = server._handle_generate_response("Hello I am MONIKA")
    print(f"Prompt: 'Hello I am MONIKA'")
    print(f"Output: '{gen_result['response']}'")
    print(f"Meta: {gen_result['meta_report']}")
    print()


def demonstrate_runtime_step_vs_training_step():
    """
    Show the difference between runtime_step and training_step.
    """
    
    print("="*80)
    print("RUNTIME_STEP vs TRAINING_STEP")
    print("="*80)
    print()
    
    print("training_step(text):")
    print("  - Direct gradient update on proto_lm")
    print("  - No salience measurement")
    print("  - No controller decision")
    print("  - No runtime orchestration")
    print("  - Just: loss.backward() + optimizer.step()")
    print()
    
    print("runtime_step(text):")
    print("  1. Sensor Bank measures salience")
    print("     → novelty, uncertainty, alignment, progress, cost, drag")
    print("  2. Controller chooses action")
    print("     → SASS, MEMORY_OP, TOOL, VERIFY, REFLECT")
    print("  3. Scheduler gates execution")
    print("     → Checks thresholds, cooldowns, budget")
    print("  4. Executor runs chosen operator")
    print("     → Maybe SASS forward pass, maybe memory op")
    print("  5. Meta-state updates")
    print("     → Confidence, difficulty, blind spots, ROI")
    print("  6. Ideas generated")
    print("     → Proposes subgoals if ROI high")
    print("  7. Adaptive tracking")
    print("     → Monitors learning dynamics")
    print()
    
    print("BOTH should be used together:")
    print("  1. training_step() updates weights")
    print("  2. runtime_step() orchestrates what/when to learn")
    print()
    
    print("Our mistake: Called training_step 5000 times")
    print("              WITHOUT runtime_step orchestration!")
    print()


def demonstrate_proper_mcp_usage():
    """
    Show the correct way to use MCP tools.
    """
    
    print("="*80)
    print("PROPER MCP USAGE PATTERN")
    print("="*80)
    print()
    
    print("WRONG (what we did):")
    print("```python")
    print("for i in range(5000):")
    print("    mcp3_fastfood(examples)  # Blind training")
    print("    # OR")
    print("    mcp3_training_step(text)  # Unconditional")
    print("```")
    print()
    
    print("RIGHT (what we should do):")
    print("```python")
    print("# Option 1: Use converse_with_monika (full flow)")
    print("result = mcp3_converse_with_monika(message)")
    print("# → Goes through process_user_input + generate_response")
    print("# → Includes salience measurement, controller, runtime")
    print()
    print("# Option 2: Use runtime_step with state")
    print("result = mcp3_runtime_step(text)")
    print("# → Full salience loop")
    print("# → Sensors + controller + scheduler + executor")
    print()
    print("# Option 3: Check yearning first, then decide")
    print("yearning = mcp3_yearning_state()")
    print("if yearning[action]['desire'] > threshold:")
    print("    mcp3_runtime_step(text)  # Only if high desire")
    print("else:")
    print("    pass  # Skip - salience too low")
    print("```")
    print()


if __name__ == "__main__":
    print()
    print("NOTE: This script shows the CONCEPTS.")
    print("      For actual training, use:")
    print("      - python train_properly.py (session-based)")
    print("      - python start.standard.py (corpus-based)")
    print("      - Or MCP tools with salience awareness")
    print()
    print("="*80)
    print()
    
    demonstrate_runtime_step_vs_training_step()
    demonstrate_proper_mcp_usage()
    
    # Uncomment to run actual test:
    # test_mcp_with_salience_awareness()
