#!/usr/bin/env python3
"""
Run All Experiments -- BSDProver v3.0.0

Reproduces all results from the paper:
  "Computational Verification and Bidirectional Information Extraction
   in the Birch and Swinnerton-Dyer Conjecture via the Fractal Correction Engine"

Usage:
    python run_all_experiments.py          # Run everything
    python run_all_experiments.py --quick  # Quick verification only (9 curves)
"""

import sys
import os
import time

# Add src directory to path
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'src'))

def run_bsd_verification():
    """Run the core 9-curve BSD verification."""
    print("=" * 72)
    print("  EXPERIMENT 0: Core BSD Verification (9 curves)")
    print("=" * 72)
    print()

    from BSDProver.main_prover import BSDProver
    prover = BSDProver()

    curves = [
        {'a': -1, 'b': 0,    'label': 'y^2=x^3-x (32.a2)'},
        {'a': 1,  'b': 0,    'label': 'y^2=x^3+x (64.a1)'},
        {'a': 0,  'b': 1,    'label': 'y^2=x^3+1 (36.a1)'},
        {'a': 0,  'b': -1,   'label': 'y^2=x^3-1 (144.a1)'},
        {'a': 0,  'b': 2,    'label': 'y^2=x^3+2 (1728.n1, rank 1)'},
        {'a': 0,  'b': -2,   'label': 'y^2=x^3-2 (1728.n2, rank 1)'},
        {'a': 0,  'b': -432, 'label': 'y^2=x^3-432 (27.a3, non-minimal)'},
        {'a': -4, 'b': 0,    'label': 'y^2=x^3-4x (128.a2)'},
        {'a': 0,  'b': -3,   'label': 'y^2=x^3-3 (rank 1)'},
    ]

    results = []
    for c in curves:
        print(f"\n--- Testing: {c['label']} ---\n")
        r = prover.test_bsd_conjecture({'a': c['a'], 'b': c['b']})
        results.append((c['label'], r))

    print("\n" + "=" * 72)
    print("  SUMMARY")
    print("=" * 72)
    passed = 0
    for label, r in results:
        status = 'PASS' if 'within' in r.verification_status else 'FAIL'
        if status == 'PASS':
            passed += 1
        ratio_str = f'{r.bsd_ratio:.10f}' if r.bsd_ratio else 'N/A'
        print(f"  {label:45s}  BSD={ratio_str}  [{status}]")
    print(f"\n  Total: {passed}/{len(results)} passed")
    print()
    return passed == len(results)


def run_experiment(script_name, description):
    """Run an experiment script from the experiments directory."""
    print("=" * 72)
    print(f"  {description}")
    print("=" * 72)
    print()

    exp_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'experiments')
    script_path = os.path.join(exp_dir, script_name)

    if not os.path.exists(script_path):
        print(f"  Script not found: {script_path}")
        return

    # Execute the script
    import importlib.util
    spec = importlib.util.spec_from_file_location("experiment", script_path)
    mod = importlib.util.module_from_spec(spec)
    sys.modules["experiment"] = mod
    spec.loader.exec_module(mod)

    # Call main function if it exists
    if hasattr(mod, 'main'):
        mod.main()
    elif hasattr(mod, 'run_convergence_analysis'):
        mod.run_convergence_analysis()


def main():
    start = time.time()
    quick = '--quick' in sys.argv

    print()
    print("  BSDProver v3.0.0 -- Full Experiment Suite")
    print("  Fractal Correction Engine for BSD Conjecture Analysis")
    print()

    # Always run core verification
    all_pass = run_bsd_verification()

    if not quick:
        # Run all FCE experiments
        experiments = [
            ('fce_convergence_spectrum.py', 'Convergence Spectrum (Analog-to-Digital Theorem)'),
            ('fce_transcendental_map.py', 'Transcendental Number Map'),
            ('fce_pi_mechanism.py', 'Pi as Rationality Mechanism'),
            ('fce_goat_translation.py', 'Bidirectional Information Extraction'),
        ]

        for script, desc in experiments:
            try:
                run_experiment(script, desc)
            except Exception as e:
                print(f"  Experiment failed: {e}")
                print()

    elapsed = time.time() - start
    print("=" * 72)
    print(f"  All experiments completed in {elapsed:.1f} seconds")
    print(f"  Core BSD verification: {'ALL PASSED' if all_pass else 'SOME FAILED'}")
    print("=" * 72)


if __name__ == "__main__":
    main()
