"""
Run all integration tests for ZeroProofML.

This script runs all integration tests and provides a comprehensive report
of the system's ability to handle singularities, control coverage, and
maintain stability during training.
"""

import sys
import time
import traceback
from typing import Dict, List, Tuple


def run_test_module(module_name: str, test_name: str) -> Tuple[bool, float, str]:
    """
    Run a test module and return results.

    Args:
        module_name: Name of the module to import
        test_name: Display name for the test

    Returns:
        (success, duration, message)
    """
    print(f"\n{'='*60}")
    print(f"Running: {test_name}")
    print("=" * 60)

    start_time = time.time()
    try:
        # Import and run the module
        if module_name == "test_synthetic_rational_regression":
            from test_synthetic_rational_regression import (
                TestConvergenceMetrics,
                TestDatasetQuality,
                TestSyntheticRationalRegression,
            )

            # Run dataset quality tests
            dataset_test = TestDatasetQuality()
            dataset_test.test_dataset_has_singularities()
            dataset_test.test_near_pole_sampling()

            # Run convergence tests
            convergence_test = TestConvergenceMetrics()
            convergence_test.test_loss_convergence()

            # Run main integration tests
            main_test = TestSyntheticRationalRegression()
            main_test.test_coverage_control_effectiveness()
            main_test.test_gradient_stability_near_poles()
            main_test.test_end_to_end_training()

        elif module_name == "test_pole_reconstruction":
            from test_pole_reconstruction import TestMultiDimensionalPoles, TestPoleReconstruction

            # Run pole reconstruction tests
            pole_test = TestPoleReconstruction()
            accuracy, ple = pole_test.test_pole_learning_with_supervision()
            metrics = pole_test.test_pole_metrics()
            pole_test.test_pole_evaluator()

            # Run multi-dimensional tests
            multi_test = TestMultiDimensionalPoles()
            multi_test.test_2d_pole_reconstruction()

        elif module_name == "test_robotics_ik_singularities":
            from test_robotics_ik_singularities import (
                TestRoboticsIKSingularities,
                TestSingularityMetrics,
            )

            # Run IK tests
            ik_test = TestRoboticsIKSingularities()
            ik_test.test_ik_with_singularities()
            ik_test.test_singularity_aware_sampling()
            ik_test.test_multiple_singularity_types()

            # Run metrics tests
            metrics_test = TestSingularityMetrics()
            metrics_test.test_singularity_coverage_metrics()
            metrics_test.test_gradient_behavior_at_singularities()

        else:
            raise ValueError(f"Unknown test module: {module_name}")

        duration = time.time() - start_time
        return True, duration, "All tests passed"

    except Exception as e:
        duration = time.time() - start_time
        error_msg = f"{type(e).__name__}: {str(e)}\n{traceback.format_exc()}"
        return False, duration, error_msg


def main():
    """Run all integration tests."""
    print("\n" + "=" * 70)
    print(" " * 20 + "ZEROPROOFML INTEGRATION TEST SUITE")
    print("=" * 70)
    print("\nThis suite validates:")
    print("  • Singularity handling in TR arithmetic")
    print("  • Coverage control with actual poles")
    print("  • Gradient stability near singularities")
    print("  • Pole detection and reconstruction")
    print("  • Real-world robotics applications")

    # Define test modules
    tests = [
        ("test_synthetic_rational_regression", "Synthetic Rational Regression"),
        ("test_pole_reconstruction", "Pole Reconstruction with Ground Truth"),
        ("test_robotics_ik_singularities", "Robotics IK with Singularities"),
    ]

    # Run all tests
    results = []
    total_time = 0

    for module_name, test_name in tests:
        success, duration, message = run_test_module(module_name, test_name)
        results.append(
            {"name": test_name, "success": success, "duration": duration, "message": message}
        )
        total_time += duration

    # Print summary
    print("\n" + "=" * 70)
    print(" " * 25 + "TEST SUMMARY")
    print("=" * 70)

    passed = sum(1 for r in results if r["success"])
    total = len(results)

    print(f"\nResults: {passed}/{total} passed")
    print(f"Total time: {total_time:.2f} seconds")
    print("\nDetailed Results:")
    print("-" * 70)

    for result in results:
        status = "✓ PASSED" if result["success"] else "✗ FAILED"
        print(f"\n{result['name']}:")
        print(f"  Status: {status}")
        print(f"  Duration: {result['duration']:.2f}s")
        if not result["success"]:
            print(f"  Error: {result['message'][:200]}...")

    # Key metrics summary
    print("\n" + "=" * 70)
    print(" " * 20 + "KEY ACHIEVEMENTS")
    print("=" * 70)

    if passed == total:
        print("\n✅ All integration tests passed!")
        print("\nVerified Capabilities:")
        print("  • Coverage control: Achieves target ±5%")
        print("  • Singularity handling: Coverage always < 100%")
        print("  • Pole detection: 80%+ accuracy (exceeds 60% requirement)")
        print("  • Gradient stability: No explosions near poles")
        print("  • λ_rej control: Stable with PI/dead-band")
        print("  • Robotics: Handles det(J)=0 singularities")
        print("  • Sampling: Importance weighting near poles")
        print("  • Metrics: PLE, sign consistency, asymptotic behavior")
    else:
        print(f"\n❌ {total - passed} test(s) failed")
        print("\nPlease review the errors above and fix the issues.")

    print("\n" + "=" * 70)

    # Return exit code
    return 0 if passed == total else 1


if __name__ == "__main__":
    exit_code = main()
    sys.exit(exit_code)
