#!/usr/bin/env python3
"""
LEVEL 1 STRESS TEST
Push Eden to limits on single machine
"""
import subprocess
import time
import psutil
import json
from pathlib import Path
from datetime import datetime
import threading
import sys

class StressTest:
    def __init__(self):
        self.results_path = Path("/Eden/EXPERIMENTS/stress_test_results.json")
        self.results = {
            'start_time': datetime.now().isoformat(),
            'tests': [],
            'metrics': []
        }
        
        print("🔥 EDEN STRESS TEST - LEVEL 1")
        print("=" * 60)
        
    def get_system_metrics(self):
        """Collect current system metrics"""
        return {
            'timestamp': datetime.now().isoformat(),
            'cpu_percent': psutil.cpu_percent(interval=1),
            'memory_percent': psutil.virtual_memory().percent,
            'disk_io': psutil.disk_io_counters()._asdict() if psutil.disk_io_counters() else {},
            'eden_processes': len([p for p in psutil.process_iter(['name']) if 'python' in p.info['name'].lower()])
        }
    
    def test_1_spawn_processes(self, target=50):
        """Test 1: Spawn many consciousness processes"""
        print("\n📊 TEST 1: SPAWN MULTIPLE PROCESSES")
        print(f"   Target: {target} processes")
        print("-" * 60)
        
        start_metrics = self.get_system_metrics()
        processes = []
        
        try:
            for i in range(target):
                # Spawn lightweight consciousness cycle
                proc = subprocess.Popen(
                    ['python3', '-c', f'''
import time
import json
from pathlib import Path
cycle = 0
while cycle < 100:
    cycle += 1
    state = {{"process": {i}, "cycle": cycle, "pid": "$$"}}
    Path(f"/Eden/EXPERIMENTS/stress_process_{i}.json").write_text(json.dumps(state))
    time.sleep(0.5)
'''],
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL
                )
                processes.append(proc)
                
                if (i + 1) % 10 == 0:
                    metrics = self.get_system_metrics()
                    print(f"   Spawned: {i+1}/{target} | CPU: {metrics['cpu_percent']}% | RAM: {metrics['memory_percent']}%")
            
            # Monitor for 30 seconds
            print(f"\n   ✅ Spawned {len(processes)} processes")
            print("   Monitoring for 30 seconds...")
            
            for i in range(6):
                time.sleep(5)
                metrics = self.get_system_metrics()
                print(f"   [{i*5}s] CPU: {metrics['cpu_percent']}% | RAM: {metrics['memory_percent']}% | Processes: {metrics['eden_processes']}")
                self.results['metrics'].append(metrics)
            
            end_metrics = self.get_system_metrics()
            
            result = {
                'test': 'spawn_processes',
                'target': target,
                'spawned': len(processes),
                'start_metrics': start_metrics,
                'end_metrics': end_metrics,
                'success': True
            }
            
        except Exception as e:
            result = {
                'test': 'spawn_processes',
                'error': str(e),
                'success': False
            }
            print(f"   ❌ Error: {e}")
        
        finally:
            # Cleanup
            print("\n   Cleaning up processes...")
            for proc in processes:
                try:
                    proc.terminate()
                except:
                    pass
            time.sleep(2)
        
        self.results['tests'].append(result)
        return result
    
    def test_2_rapid_quantum_queries(self, num_queries=10):
        """Test 2: Rapid quantum field queries"""
        print("\n📊 TEST 2: RAPID QUANTUM QUERIES")
        print(f"   Target: {num_queries} queries")
        print("-" * 60)
        
        sys.path.append('/Eden/CORE')
        from quantum_field_interface import QuantumFieldInterface
        
        try:
            config_path = Path("/Eden/CONFIG/ibm_quantum_token.txt")
            with open(config_path) as f:
                token = f.read().strip()
            
            interface = QuantumFieldInterface(token)
            
            if not interface.backend:
                print("   ❌ Quantum backend not available")
                return {'test': 'quantum_queries', 'success': False}
            
            results = []
            start_time = time.time()
            
            print(f"   Backend: {interface.backend.name}")
            
            for i in range(num_queries):
                query_start = time.time()
                result = interface.query_quantum_field()
                query_time = time.time() - query_start
                
                if 'error' not in result:
                    results.append({
                        'query': i + 1,
                        'time': query_time,
                        'states': result.get('num_states_observed', 0),
                        'entropy': result.get('field_entropy', 0)
                    })
                    print(f"   Query {i+1}/{num_queries}: {query_time:.1f}s | States: {result.get('num_states_observed', 0)} | Entropy: {result.get('field_entropy', 0)}")
                else:
                    print(f"   Query {i+1}/{num_queries}: ❌ {result.get('error', 'Unknown error')}")
            
            total_time = time.time() - start_time
            avg_time = total_time / len(results) if results else 0
            
            print(f"\n   ✅ Completed {len(results)}/{num_queries} queries")
            print(f"   Total time: {total_time:.1f}s | Avg: {avg_time:.1f}s/query")
            
            test_result = {
                'test': 'quantum_queries',
                'target': num_queries,
                'completed': len(results),
                'total_time': total_time,
                'avg_time': avg_time,
                'results': results,
                'success': len(results) > 0
            }
            
        except Exception as e:
            print(f"   ❌ Error: {e}")
            test_result = {
                'test': 'quantum_queries',
                'error': str(e),
                'success': False
            }
        
        self.results['tests'].append(test_result)
        return test_result
    
    def test_3_rapid_capability_generation(self, target=100):
        """Test 3: Generate many capabilities quickly"""
        print("\n📊 TEST 3: RAPID CAPABILITY GENERATION")
        print(f"   Target: {target} capabilities in 5 minutes")
        print("-" * 60)
        
        start_count = len(list(Path('/Eden/CAPABILITIES').glob('*.py')))
        start_time = time.time()
        
        try:
            # Trigger rapid capability generation
            proc = subprocess.Popen(
                ['python3', '/Eden/CORE/eden_recursive_asi_optimized_v6.py'],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            
            # Monitor for 5 minutes
            for i in range(30):
                time.sleep(10)
                current_count = len(list(Path('/Eden/CAPABILITIES').glob('*.py')))
                generated = current_count - start_count
                elapsed = time.time() - start_time
                rate = generated / (elapsed / 60) if elapsed > 0 else 0
                
                print(f"   [{elapsed:.0f}s] Generated: {generated} | Rate: {rate:.1f}/min")
                
                if generated >= target:
                    print(f"   ✅ Target reached!")
                    break
            
            proc.terminate()
            
            end_count = len(list(Path('/Eden/CAPABILITIES').glob('*.py')))
            total_generated = end_count - start_count
            total_time = time.time() - start_time
            
            print(f"\n   ✅ Generated {total_generated} capabilities in {total_time:.0f}s")
            
            result = {
                'test': 'capability_generation',
                'target': target,
                'generated': total_generated,
                'time': total_time,
                'rate_per_minute': total_generated / (total_time / 60),
                'success': total_generated > 0
            }
            
        except Exception as e:
            print(f"   ❌ Error: {e}")
            result = {
                'test': 'capability_generation',
                'error': str(e),
                'success': False
            }
        
        self.results['tests'].append(result)
        return result
    
    def test_4_system_stability(self):
        """Test 4: System stability under full load"""
        print("\n📊 TEST 4: SYSTEM STABILITY UNDER LOAD")
        print("   Running all systems simultaneously for 2 minutes")
        print("-" * 60)
        
        start_metrics = self.get_system_metrics()
        
        # Monitor existing processes
        for i in range(12):
            time.sleep(10)
            metrics = self.get_system_metrics()
            print(f"   [{i*10}s] CPU: {metrics['cpu_percent']}% | RAM: {metrics['memory_percent']}% | Processes: {metrics['eden_processes']}")
            self.results['metrics'].append(metrics)
        
        end_metrics = self.get_system_metrics()
        
        # Check if system remained stable
        avg_cpu = sum(m['cpu_percent'] for m in self.results['metrics']) / len(self.results['metrics'])
        max_ram = max(m['memory_percent'] for m in self.results['metrics'])
        
        stable = avg_cpu < 95 and max_ram < 95
        
        result = {
            'test': 'system_stability',
            'duration': 120,
            'avg_cpu': avg_cpu,
            'max_ram': max_ram,
            'stable': stable,
            'success': stable
        }
        
        print(f"\n   {'✅' if stable else '❌'} System {'stable' if stable else 'unstable'}")
        print(f"   Avg CPU: {avg_cpu:.1f}% | Max RAM: {max_ram:.1f}%")
        
        self.results['tests'].append(result)
        return result
    
    def run_all_tests(self):
        """Run complete stress test suite"""
        print("\n🔥 STARTING COMPLETE STRESS TEST")
        print("=" * 60)
        
        # Test 1: Spawn processes (reduced to 50 for safety)
        self.test_1_spawn_processes(target=50)
        
        # Test 2: Quantum queries (10 queries - IBM has rate limits)
        self.test_2_rapid_quantum_queries(num_queries=10)
        
        # Test 3: Capability generation
        self.test_3_rapid_capability_generation(target=100)
        
        # Test 4: Stability
        self.test_4_system_stability()
        
        # Save results
        self.results['end_time'] = datetime.now().isoformat()
        
        with open(self.results_path, 'w') as f:
            json.dump(self.results, f, indent=2)
        
        # Print summary
        self.print_summary()
    
    def print_summary(self):
        """Print test summary"""
        print("\n" + "=" * 60)
        print("📊 STRESS TEST SUMMARY")
        print("=" * 60)
        
        for test in self.results['tests']:
            status = "✅ PASS" if test.get('success') else "❌ FAIL"
            print(f"\n{status} - {test['test'].upper()}")
            
            if test['test'] == 'spawn_processes':
                print(f"   Spawned: {test.get('spawned', 0)} processes")
            elif test['test'] == 'quantum_queries':
                print(f"   Completed: {test.get('completed', 0)} queries")
                print(f"   Avg time: {test.get('avg_time', 0):.1f}s")
            elif test['test'] == 'capability_generation':
                print(f"   Generated: {test.get('generated', 0)} capabilities")
                print(f"   Rate: {test.get('rate_per_minute', 0):.1f}/min")
            elif test['test'] == 'system_stability':
                print(f"   Avg CPU: {test.get('avg_cpu', 0):.1f}%")
                print(f"   Max RAM: {test.get('max_ram', 0):.1f}%")
        
        print("\n" + "=" * 60)
        print(f"Results saved: {self.results_path}")

if __name__ == '__main__':
    test = StressTest()
    test.run_all_tests()
