#!/usr/bin/env python3
"""
DETAILED SIMULATION INVESTIGATION
Focus on Critical Issues Identified in Forensic Analysis

Issues to investigate:
1. Boundary Physics Critical Fail
2. Boundary Evolution Divergence
"""

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
import json

class DetailedInvestigation:
    """Deep dive into the critical issues"""
    
    def __init__(self):
        self.investigation_results = {}
    
    def investigate_boundary_physics_issue(self):
        """Investigate the boundary physics critical failure"""
        print("INVESTIGATING BOUNDARY PHYSICS CRITICAL FAILURE")
        print("=" * 60)
        
        # The issue is likely in phase continuity validation
        N_values = [6, 12, 18, 36, 72]
        results = {}
        
        for N in N_values:
            theta = np.linspace(0, 2*np.pi, N, endpoint=False)
            
            # Test various phase functions
            test_functions = {
                "smooth_sine": np.sin(3*theta) + 0.5*np.cos(5*theta),
                "high_frequency": np.sin(12*theta),  # May cause issues
                "discontinuous": np.where(theta < np.pi, 1.0, -1.0),  # Intentionally problematic
                "smooth_polynomial": theta**2 - 2*np.pi*theta,
                "wrapped_continuous": np.sin(theta) + 0.1*np.sin(7*theta)
            }
            
            results[N] = {}
            
            for func_name, phase in test_functions.items():
                # Check phase continuity
                phase_diff = np.diff(phase)
                # Handle wrap-around for circular boundary
                phase_diff = np.append(phase_diff, phase[0] - phase[-1])
                
                max_discontinuity = np.max(np.abs(phase_diff))
                threshold = np.pi / 20  # From dossier specification
                
                results[N][func_name] = {
                    "max_discontinuity": max_discontinuity,
                    "threshold": threshold,
                    "passes": max_discontinuity < threshold,
                    "phase_range": np.max(phase) - np.min(phase)
                }
                
                print(f"N={N:2d}, {func_name:18s}: "
                      f"max_disc={max_discontinuity:.4f}, "
                      f"thresh={threshold:.4f}, "
                      f"{'PASS' if max_discontinuity < threshold else 'FAIL'}")
        
        print()
        return results
    
    def investigate_evolution_divergence(self):
        """Investigate why boundary evolution diverges"""
        print("INVESTIGATING BOUNDARY EVOLUTION DIVERGENCE")
        print("=" * 60)
        
        N = 18
        theta = np.linspace(0, 2*np.pi, N, endpoint=False)
        
        # Test different parameters
        alpha_values = [0.01, 0.05, 0.1, 0.2, 0.5]
        dt_values = [0.0001, 0.001, 0.01, 0.1]
        
        results = {}
        
        for alpha in alpha_values:
            results[alpha] = {}
            
            for dt in dt_values:
                # Initial condition
                I = np.exp(-((theta - np.pi)**2) / 0.5)
                I = I / np.sum(I)
                
                # Check stability condition for explicit scheme
                # For diffusion: dt â‰¤ dxÂ²/(2Î±) for stability
                dx = 2*np.pi / N  # Angular spacing
                stability_limit = dx**2 / (2*alpha)
                stable = dt <= stability_limit
                
                # Run short simulation
                steps = 100
                energy_history = []
                max_value_history = []
                
                try:
                    for step in range(steps):
                        # Energy tracking
                        energy = 0.5 * np.sum(I**2)
                        energy_history.append(energy)
                        max_value_history.append(np.max(I))
                        
                        # Evolution step
                        I_new = np.copy(I)
                        for i in range(N):
                            im1 = (i - 1) % N
                            ip1 = (i + 1) % N
                            laplacian = I[ip1] - 2*I[i] + I[im1]
                            I_new[i] = I[i] + alpha * dt * laplacian
                        
                        I = I_new
                        
                        # Check for divergence
                        if np.any(np.isnan(I)) or np.any(np.abs(I) > 100):
                            break
                        
                        # Renormalize
                        I = I / np.sum(I)
                    
                    final_energy = energy_history[-1] if energy_history else float('inf')
                    converged = abs(final_energy - 1.0/(2*N)) < 0.01  # Uniform distribution energy
                    
                except:
                    converged = False
                    final_energy = float('inf')
                
                results[alpha][dt] = {
                    "stable": stable,
                    "stability_limit": stability_limit,
                    "converged": converged,
                    "final_energy": final_energy,
                    "energy_history": energy_history[:10],  # First 10 values
                }
                
                status = "âœ…" if (stable and converged) else ("âš ï¸" if stable else "âŒ")
                print(f"Î±={alpha:.2f}, dt={dt:.4f}: {status} "
                      f"stable={stable}, converged={converged}, "
                      f"limit={stability_limit:.6f}")
        
        print()
        return results
    
    def investigate_correct_formulation(self):
        """Investigate the correct mathematical formulation"""
        print("INVESTIGATING CORRECT MATHEMATICAL FORMULATION")
        print("=" * 60)
        
        N = 18
        theta = np.linspace(0, 2*np.pi, N, endpoint=False)
        
        # The dossier mentions this should be a diffusion-like process
        # Let's implement it correctly as a PDE
        
        def diffusion_rhs(t, I_flat):
            """Right-hand side for the diffusion equation dI/dt = Î±âˆ‡Â²I"""
            I = I_flat.reshape(N)
            
            # Discrete Laplacian on circular boundary
            dI_dt = np.zeros(N)
            for i in range(N):
                im1 = (i - 1) % N
                ip1 = (i + 1) % N
                # Scale properly: Laplacian = (I[i+1] - 2I[i] + I[i-1]) / (Î”Î¸)Â²
                dtheta = 2*np.pi / N
                laplacian = (I[ip1] - 2*I[i] + I[im1]) / (dtheta**2)
                dI_dt[i] = 0.1 * laplacian  # Î± = 0.1
            
            return dI_dt
        
        # Initial condition
        I0 = np.exp(-((theta - np.pi)**2) / 0.5)
        I0 = I0 / np.sum(I0)
        
        # Solve using proper ODE solver
        t_span = (0, 5.0)
        t_eval = np.linspace(0, 5.0, 100)
        
        sol = solve_ivp(diffusion_rhs, t_span, I0, t_eval=t_eval, method='RK45', rtol=1e-8)
        
        if sol.success:
            I_final = sol.y[:, -1]
            I_uniform = np.ones(N) / N
            
            error_to_uniform = np.sqrt(np.mean((I_final - I_uniform)**2))
            
            # Check conservation
            conservation_errors = [abs(np.sum(sol.y[:, i]) - 1.0) for i in range(len(t_eval))]
            max_conservation_error = max(conservation_errors)
            
            print(f"ODE Solver SUCCESS:")
            print(f"  Error to uniform: {error_to_uniform:.6f}")
            print(f"  Max conservation error: {max_conservation_error:.2e}")
            print(f"  Final sum: {np.sum(I_final):.10f}")
            
            # Analytical solution check
            # For diffusion on a circle, the solution should decay to uniform
            # with rate proportional to eigenvalues of Laplacian
            eigenvalues = [-k**2 for k in range(N//2)]  # Discrete Laplacian eigenvalues
            print(f"  First few eigenvalues: {eigenvalues[:5]}")
            
            return {
                "success": True,
                "error_to_uniform": error_to_uniform,
                "conservation_error": max_conservation_error,
                "solution": sol,
                "converges_properly": error_to_uniform < 0.01
            }
        else:
            print("ODE Solver FAILED")
            return {"success": False}
    
    def investigate_geometric_consistency(self):
        """Check geometric consistency with hexOSAI principles"""
        print("INVESTIGATING GEOMETRIC CONSISTENCY WITH HEXOSAI")
        print("=" * 60)
        
        # Check if the geometry aligns with Marcel's hexagonal principles
        
        # 6-sector case (hexagonal)
        N6 = 6
        theta6 = np.linspace(0, 2*np.pi, N6, endpoint=False)
        
        # Verify hexagonal angles
        expected_angles = np.array([0, Ï€/3, 2*Ï€/3, Ï€, 4*Ï€/3, 5*Ï€/3])
        actual_angles = theta6
        
        angle_errors = np.abs(actual_angles - expected_angles)
        max_angle_error = np.max(angle_errors)
        
        print(f"Hexagonal geometry validation:")
        print(f"  Expected angles: {expected_angles}")
        print(f"  Actual angles:   {actual_angles}")
        print(f"  Max error:       {max_angle_error:.6f} radians")
        print(f"  Hexagonal compliance: {'âœ…' if max_angle_error < 1e-10 else 'âŒ'}")
        
        # 18-sector case (3Ã—6 refinement)
        N18 = 18
        theta18 = np.linspace(0, 2*np.pi, N18, endpoint=False)
        
        # Check if it's a proper subdivision
        subdivision_valid = all(abs(theta18[3*i] - theta6[i]) < 1e-10 for i in range(6))
        
        print(f"18-sector subdivision validation:")
        print(f"  Proper 3Ã— subdivision: {'âœ…' if subdivision_valid else 'âŒ'}")
        
        # Field Vector Architecture compliance
        # Check if the discrete field satisfies FVA deterministic topology
        I_test = np.ones(N6) / N6  # Uniform field
        
        # FVA test: structural coherence
        coherence = np.var(I_test)  # Should be minimal for uniform
        fva_compliant = coherence < 1e-10
        
        print(f"Field Vector Architecture compliance:")
        print(f"  Structural coherence: {coherence:.2e}")
        print(f"  FVA compliant:        {'âœ…' if fva_compliant else 'âŒ'}")
        
        return {
            "hexagonal_compliant": max_angle_error < 1e-10,
            "subdivision_valid": subdivision_valid,
            "fva_compliant": fva_compliant,
            "max_angle_error": max_angle_error,
            "structural_coherence": coherence
        }

def run_detailed_investigation():
    """Run the complete detailed investigation"""
    investigator = DetailedInvestigation()
    
    print("DETAILED FORENSIC INVESTIGATION")
    print("Quartz Optical Computing Chip Dossier")
    print("Critical Issue Analysis")
    print("="*80)
    print()
    
    # Investigate all critical issues
    boundary_results = investigator.investigate_boundary_physics_issue()
    evolution_results = investigator.investigate_evolution_divergence()
    formulation_results = investigator.investigate_correct_formulation()
    geometry_results = investigator.investigate_geometric_consistency()
    
    # Summary
    print("INVESTIGATION SUMMARY")
    print("=" * 40)
    
    if formulation_results["success"]:
        print("âœ… CORRECTED FORMULATION WORKS")
        print(f"   Converges to uniform: {'Yes' if formulation_results['converges_properly'] else 'No'}")
    else:
        print("âŒ FORMULATION ISSUES PERSIST")
    
    if geometry_results["hexagonal_compliant"]:
        print("âœ… HEXAGONAL GEOMETRY VALID")
    else:
        print("âŒ GEOMETRY ISSUES DETECTED")
    
    if geometry_results["fva_compliant"]:
        print("âœ… FVA COMPLIANT")
    else:
        print("âš ï¸  FVA COMPLIANCE QUESTIONABLE")
    
    # Save detailed investigation
    investigation_data = {
        "boundary_physics": boundary_results,
        "evolution_analysis": evolution_results,
        "correct_formulation": {k: v for k, v in formulation_results.items() if k != "solution"},
        "geometry_analysis": geometry_results
    }
    
    with open('/home/claude/detailed_investigation.json', 'w') as f:
        json.dump(investigation_data, f, indent=2, default=str)
    
    print()
    print("ðŸ“Š Detailed investigation saved to detailed_investigation.json")
    
    return investigation_data

if __name__ == "__main__":
    # Make sure numpy is using the right value for pi
    global Ï€
    Ï€ = np.pi
    
    results = run_detailed_investigation()
