#!/usr/bin/env python3
"""
Interactive debugging for StreamLens button issues
Run this and interact with the live app while monitoring button states
"""

import sys
import time
import threading
from pathlib import Path

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

from analyzer.tui.textual.app_v2 import StreamLensAppV2
from analyzer.analysis.core import EthernetAnalyzer
from textual_state_visualizer import TextualStateMonitor, TextualStateWebServer

class InteractiveDebugger:
    """Interactive debugger that monitors button states in real-time"""
    
    def __init__(self):
        self.analyzer = None
        self.app = None
        self.monitor = None
        self.web_server = None
        self.monitoring = False
        
    def setup_analyzer_with_data(self):
        """Create analyzer with some sample data"""
        from analyzer.models.flow_stats import FlowStats, FrameTypeStats
        
        self.analyzer = EthernetAnalyzer()
        
        # Add sample flows to trigger button updates
        flow1 = FlowStats(src_ip="192.168.1.1", dst_ip="192.168.1.2")
        flow1.frame_types["CH10-Data"] = FrameTypeStats("CH10-Data", count=1500)
        flow1.frame_types["UDP"] = FrameTypeStats("UDP", count=800)
        self.analyzer.flows["flow1"] = flow1
        
        flow2 = FlowStats(src_ip="192.168.1.3", dst_ip="192.168.1.4") 
        flow2.frame_types["PTP-Sync"] = FrameTypeStats("PTP-Sync", count=600)
        flow2.frame_types["PTP-Signaling"] = FrameTypeStats("PTP-Signaling", count=300)
        self.analyzer.flows["flow2"] = flow2
        
        print("📊 Sample data added to analyzer:")
        print("   Flow 1: CH10-Data(1500), UDP(800)")
        print("   Flow 2: PTP-Sync(600), PTP-Signaling(300)")
        
    def start_debugging(self):
        """Start the app with full debugging enabled"""
        print("🚀 Starting StreamLens with interactive debugging...")
        
        # Setup analyzer
        self.setup_analyzer_with_data()
        
        # Create app
        self.app = StreamLensAppV2(analyzer=self.analyzer)
        
        # Start state monitoring
        self.monitor = TextualStateMonitor(self.app)
        self.monitor.start_monitoring(interval=0.5)  # Monitor every 500ms
        
        # Start web interface
        self.web_server = TextualStateWebServer(self.monitor, port=8080)
        self.web_server.start()
        
        print("🌐 Web debugging interface: http://localhost:8080")
        print("📱 Starting StreamLens app...")
        print()
        print("🔧 DEBUGGING COMMANDS (while app is running):")
        print("   Ctrl+D,T - Print widget tree to console")
        print("   Ctrl+D,F - Show focused widget")
        print("   Ctrl+D,W - Start additional web debugger")
        print()
        print("🧪 INTERACTIVE TESTING:")
        print("   1. Watch the web interface in your browser")
        print("   2. Try loading a PCAP file in the app")
        print("   3. Watch for button changes in real-time")
        print("   4. Use keyboard shortcuts to debug instantly")
        print()
        print("📊 The web interface will show:")
        print("   - Real-time widget tree")
        print("   - Button count and properties") 
        print("   - State changes as they happen")
        print("   - Focus tracking")
        print()
        
        # Run the app
        try:
            self.app.run()
        except KeyboardInterrupt:
            print("\n🛑 App stopped by user")
        finally:
            self.cleanup()
    
    def cleanup(self):
        """Clean up debugging resources"""
        print("\n🧹 Cleaning up debugging...")
        if self.monitor:
            self.monitor.stop_monitoring()
        if self.web_server:
            self.web_server.stop()

def create_vscode_debug_config():
    """Create VS Code debug configuration"""
    vscode_config = {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Debug StreamLens Interactive",
                "type": "python",
                "request": "launch",
                "program": "${workspaceFolder}/interactive_debug.py",
                "console": "integratedTerminal",
                "justMyCode": False,
                "env": {
                    "PYTHONPATH": "${workspaceFolder}"
                }
            },
            {
                "name": "Debug StreamLens Button Issues",
                "type": "python", 
                "request": "launch",
                "program": "${workspaceFolder}/debug_button_issues.py",
                "console": "integratedTerminal",
                "justMyCode": False,
                "env": {
                    "PYTHONPATH": "${workspaceFolder}"
                }
            }
        ]
    }
    
    # Create .vscode directory if it doesn't exist
    vscode_dir = Path(".vscode")
    vscode_dir.mkdir(exist_ok=True)
    
    # Write launch.json
    import json
    launch_json = vscode_dir / "launch.json"
    with open(launch_json, 'w') as f:
        json.dump(vscode_config, f, indent=4)
    
    print(f"✅ Created VS Code debug configuration: {launch_json}")

def create_breakpoint_helper():
    """Create a helper script with strategic breakpoints"""
    
    breakpoint_script = '''
# Add these breakpoints to key locations for debugging

# 1. In filtered_flow_view.py - refresh_frame_types method
def refresh_frame_types(self):
    """Update frame type button counts and reorder by count (highest to left)"""
    import pdb; pdb.set_trace()  # BREAKPOINT: Start of refresh
    
    # Throttle button refresh to prevent race conditions
    import time
    current_time = time.time()
    if current_time - self._last_refresh_time < self._refresh_throttle_seconds:
        print(f"🚫 Refresh throttled (last: {self._last_refresh_time}, current: {current_time})")
        return  # Skip refresh if called too recently
    
    print(f"🔄 Starting refresh_frame_types at {current_time}")
    self._last_refresh_time = current_time
    
    # Get all detected frame types with their total packet counts
    frame_types = self._get_all_frame_types()
    print(f"📊 Frame types found: {frame_types}")
    
    # If no frame types yet, skip button update
    if not frame_types:
        print("⚠️  No frame types, skipping button update")
        return
    
    # BREAKPOINT: Before button removal/creation
    import pdb; pdb.set_trace()
    
    # Rest of method...

# 2. In filtered_flow_view.py - compose method  
def compose(self):
    """Create the filter bar and flow grid"""
    import pdb; pdb.set_trace()  # BREAKPOINT: Widget creation
    
    # Filter button bar at top
    with Horizontal(id="filter-bar"):
        # Overview button (hotkey 1) - compact format
        overview_btn = Button("1.Overview", id="btn-overview", classes="-active")
        self.frame_type_buttons["Overview"] = overview_btn
        print(f"✅ Created overview button: {overview_btn}")
        yield overview_btn
        
        # Create predefined frame type buttons at initialization
        hotkeys = ['2', '3', '4', '5', '6', '7', '8', '9', '0']
        for i, frame_type in enumerate(self.predefined_frame_types):
            if i < len(hotkeys):
                # Start with 0 count - will be updated during data refresh
                btn = FrameTypeButton(frame_type, hotkeys[i], 0)
                self.frame_type_buttons[frame_type] = btn
                print(f"✅ Created predefined button {i+1}: {btn} for {frame_type}")
                yield btn
    
    # BREAKPOINT: After all buttons created
    import pdb; pdb.set_trace()

# 3. Strategic print statements for tracking
def debug_button_lifecycle():
    """Add this to track button lifecycle"""
    
    def log_button_state(self, phase):
        print(f"\\n🔍 BUTTON STATE - {phase}:")
        print(f"   Buttons dict: {len(self.frame_type_buttons)} entries")
        for name, btn in self.frame_type_buttons.items():
            if hasattr(btn, 'parent'):
                parent_status = "has parent" if btn.parent else "NO PARENT"
            else:
                parent_status = "no parent attr"
            print(f"     {name}: {btn} ({parent_status})")
'''
    
    with open("debugging_breakpoints.py", 'w') as f:
        f.write(breakpoint_script)
        
    print("✅ Created debugging_breakpoints.py with strategic breakpoint locations")

def main():
    print("🔧 StreamLens Interactive Debugging Setup")
    print("=" * 60)
    
    # Create VS Code configuration
    create_vscode_debug_config()
    
    # Create breakpoint helper
    create_breakpoint_helper()
    
    print("\n🎯 RECOMMENDED DEBUGGING APPROACH:")
    print("\n1. **VS Code Debugging**:")
    print("   - Open this project in VS Code")
    print("   - Use F5 to start 'Debug StreamLens Interactive'")
    print("   - Set breakpoints in filtered_flow_view.py")
    print("   - Step through button creation/refresh logic")
    
    print("\n2. **Interactive Monitoring**:")
    print("   - Run: python interactive_debug.py")
    print("   - Open http://localhost:8080 in browser")
    print("   - Load a PCAP file and watch real-time changes")
    
    print("\n3. **Strategic Breakpoints**:")
    print("   - Add breakpoints at:")
    print("     • filtered_flow_view.py:142 (compose method)")
    print("     • filtered_flow_view.py:219 (refresh_frame_types method)")
    print("     • filtered_flow_view.py:171 (on_mount method)")
    
    print("\n4. **Live Console Debugging**:")
    print("   - While app runs, press Ctrl+D,T for widget tree")
    print("   - Check button parent relationships")
    print("   - Monitor refresh timing")
    
    print("\n🔍 KEY THINGS TO CHECK:")
    print("   ✓ Are buttons created in compose()?")
    print("   ✓ Do buttons have parents after creation?") 
    print("   ✓ What triggers refresh_frame_types()?")
    print("   ✓ Are buttons removed during refresh?")
    print("   ✓ What's the order of operations?")
    
    choice = input("\n❓ Start interactive debugging now? (y/N): ").lower().strip()
    
    if choice in ['y', 'yes']:
        debugger = InteractiveDebugger()
        debugger.start_debugging()
    else:
        print("\n📝 Setup complete! Use VS Code or run interactive_debug.py when ready.")

if __name__ == "__main__":
    main()