#!/usr/bin/env python3
"""Comprehensive MONIKA introspection test - checking all tools and capabilities."""

import asyncio
import json
from pathlib import Path
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client


async def test_all_capabilities():
    """Systematically test every MONIKA capability."""
    
    server_script = Path(__file__).parent / "start_mcp_server.py"
    server_params = StdioServerParameters(
        command="python",
        args=[str(server_script)],
        env=None,
    )
    
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            
            print("=" * 70)
            print("MONIKA FULL CAPABILITY INTROSPECTION")
            print("=" * 70)
            
            # List all tools
            tools_result = await session.list_tools()
            tools = {tool.name: tool for tool in tools_result.tools}
            print(f"\n✓ Found {len(tools)} tools")
            for name in sorted(tools.keys()):
                print(f"  • {name}")
            
            # Test 1: Initial state
            print("\n" + "=" * 70)
            print("TEST 1: Initial State Inspection")
            print("=" * 70)
            
            # Get yearning state
            result = await session.call_tool("yearning_state", {})
            yearning = json.loads(result.content[0].text)
            
            print("\n📊 Yearning State:")
            non_zero = {k: v for k, v in yearning.items() 
                       if isinstance(v, dict) and v.get('yearning', 0) != 0}
            if non_zero:
                for key, val in non_zero.items():
                    print(f"  {key}: {val}")
            else:
                print("  ⚠️  All yearning values are zero!")
                print(f"  Total yearning dimensions: {len(yearning)}")
            
            # Get controller dynamics
            result = await session.call_tool("controller_dynamics", {})
            dynamics = json.loads(result.content[0].text)
            print("\n🎮 Controller Dynamics:")
            print(f"  Last action: {dynamics.get('last_action', 'None')}")
            print(f"  Number of actions: {len(dynamics.get('scores', {}))}")
            
            # Get memory snapshot
            result = await session.call_tool("memory_snapshot", {})
            memory = json.loads(result.content[0].text)
            print("\n🧠 Memory State:")
            print(f"  Facts: {len(memory.get('facts', []))}")
            print(f"  Hypotheses: {len(memory.get('hypotheses', []))}")
            print(f"  Todos: {len(memory.get('todos', []))}")
            
            # Test 2: Inject stimulus and watch yearning change
            print("\n" + "=" * 70)
            print("TEST 2: Stimulus Response (Does yearning activate?)")
            print("=" * 70)
            
            result = await session.call_tool("runtime_step", {
                "text": "Let's explore a complex mathematical concept involving topology and how it relates to consciousness."
            })
            step_result = json.loads(result.content[0].text)
            print(f"\n✓ Runtime step executed: {step_result['step']}")
            print(f"  Verification passed: {step_result.get('verification_passed')}")
            print(f"  Budget left: {step_result.get('budget_left')}")
            
            # Check if yearning changed
            yearning_after = step_result.get('yearning', {})
            if yearning_after:
                print("\n📊 Yearning after stimulus:")
                non_zero_after = {k: v for k, v in yearning_after.items() 
                                 if isinstance(v, dict) and v.get('yearning', 0) != 0}
                if non_zero_after:
                    for key, val in list(non_zero_after.items())[:5]:
                        print(f"  {key}: {val}")
                else:
                    print("  ⚠️  Still all zeros - yearning may not be activating!")
            
            # Test 3: Memory operations
            print("\n" + "=" * 70)
            print("TEST 3: Memory Operations")
            print("=" * 70)
            
            # Add a fact
            result = await session.call_tool("memory_apply", {
                "verb": {"op": "add_fact", "text": "MONIKA is a salience-driven AI", "score": 1.0}
            })
            fact_result = json.loads(result.content[0].text)
            print(f"\n✓ Added fact: {fact_result['applied']}")
            if fact_result.get('new_records'):
                print(f"  New record ID: {fact_result['new_records'][0]['id']}")
            
            # Add a hypothesis
            result = await session.call_tool("memory_apply", {
                "verb": {"op": "promote_hypothesis", "text": "4D reasoning requires tracking temporal dependencies", "score": 0.8}
            })
            hyp_result = json.loads(result.content[0].text)
            print(f"✓ Added hypothesis: {hyp_result['applied']}")
            
            # Add a todo
            result = await session.call_tool("memory_apply", {
                "verb": {"op": "schedule_todo", "text": "Test 4D scratchpad functionality", "score": 0.9}
            })
            todo_result = json.loads(result.content[0].text)
            print(f"✓ Added todo: {todo_result['applied']}")
            
            # Check memory again
            result = await session.call_tool("memory_snapshot", {})
            memory_after = json.loads(result.content[0].text)
            print(f"\n📝 Memory after additions:")
            print(f"  Facts: {len(memory_after.get('facts', []))}")
            print(f"  Hypotheses: {len(memory_after.get('hypotheses', []))}")  
            print(f"  Todos: {len(memory_after.get('todos', []))}")
            
            # Test 4: Controller dynamics adjustment
            print("\n" + "=" * 70)
            print("TEST 4: Controller Dynamics Adjustment")
            print("=" * 70)
            
            result = await session.call_tool("adjust_controller_dynamics", {
                "updates": {"novelty_weight": 0.05, "coherence_weight": -0.02},
                "max_step": 0.1
            })
            adjust_result = json.loads(result.content[0].text)
            print(f"\n✓ Adjustment applied: {adjust_result.get('applied', {})}")
            
            # Test 5: Training step
            print("\n" + "=" * 70)
            print("TEST 5: Training Step")
            print("=" * 70)
            
            result = await session.call_tool("get_training_metrics", {})
            metrics_before = json.loads(result.content[0].text)
            print(f"\n📊 Before training:")
            print(f"  Step: {metrics_before['step']}")
            print(f"  Vocab size: {metrics_before['vocab_size']}")
            
            result = await session.call_tool("training_step", {
                "text": "The concept of salience weighting allows for dynamic prioritization of cognitive operations based on current context and goals."
            })
            training_result = json.loads(result.content[0].text)
            print(f"\n✓ Training step complete")
            print(f"  New step: {training_result['step']}")
            
            # Test 6: Generate response
            print("\n" + "=" * 70)
            print("TEST 6: Response Generation")
            print("=" * 70)
            
            result = await session.call_tool("generate_response", {
                "prompt": "Explain how salience-driven reasoning differs from traditional attention mechanisms."
            })
            gen_result = json.loads(result.content[0].text)
            print(f"\n✓ Response generated:")
            print(f"  Step: {gen_result['step']}")
            print(f"  Response preview: {gen_result['response'][:200]}...")
            if gen_result.get('todos'):
                print(f"  Generated todos: {len(gen_result['todos'])}")
            
            # Test 7: Workspace listing
            print("\n" + "=" * 70)
            print("TEST 7: Workspace Introspection")
            print("=" * 70)
            
            result = await session.call_tool("workspace_listing", {"path": "."})
            workspace = json.loads(result.content[0].text)
            print(f"\n📁 Workspace entries: {len(workspace)}")
            if workspace:
                for entry in workspace[:5]:
                    print(f"  • {entry}")
            
            # Test 8: Look for missing capabilities
            print("\n" + "=" * 70)
            print("TEST 8: Capability Gap Analysis")
            print("=" * 70)
            
            expected_capabilities = [
                "4d_scratchpad",
                "4d_reasoning_step", 
                "temporal_dependency_tracking",
                "sass_operation",
                "sass_with_jump",
                "reflection_step",
                "verify_step",
                "tool_invocation",
                "meta_report",
            ]
            
            print("\n🔍 Checking for expected capabilities:")
            missing = []
            for cap in expected_capabilities:
                if cap not in tools:
                    missing.append(cap)
                    print(f"  ❌ MISSING: {cap}")
                else:
                    print(f"  ✓ Found: {cap}")
            
            if missing:
                print(f"\n⚠️  {len(missing)} capabilities not exposed via MCP!")
                print("These should probably be wired up:")
                for cap in missing:
                    print(f"  • {cap}")
            
            # Final summary
            print("\n" + "=" * 70)
            print("INTROSPECTION COMPLETE")
            print("=" * 70)
            print(f"\n✓ Total tools tested: {len(tools)}")
            print(f"⚠️  Missing capabilities: {len(missing)}")


if __name__ == "__main__":
    asyncio.run(test_all_capabilities())
