#!/usr/bin/env python
"""
Comprehensive test suite runner for the comprehensive-reports-and-fixes spec.

This script runs all unit tests and property-based tests with coverage reporting.
It validates that:
- All unit tests pass
- All property-based tests pass with minimum 100 iterations
- Code coverage meets the 80% threshold for modified modules
"""

import os
import sys
import django
import subprocess
from pathlib import Path

# Setup Django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'branch_system.settings')
django.setup()

def print_header(text):
    """Print a formatted header."""
    print("\n" + "=" * 80)
    print(f"  {text}")
    print("=" * 80 + "\n")

def run_command(command, description):
    """Run a command and return success status."""
    print(f"\n🔍 {description}...")
    print(f"Command: {command}\n")
    
    result = subprocess.run(
        command,
        shell=True,
        capture_output=False,
        text=True
    )
    
    return result.returncode == 0

def main():
    """Run the full test suite."""
    print_header("COMPREHENSIVE REPORTS AND FIXES - FULL TEST SUITE")
    
    results = {}
    
    # Test modules for this spec
    test_modules = [
        # Disbursed Loans Report Tests
        ("test_disbursed_loans_report", "Disbursed Loans Report Unit Tests"),
        ("loans.test_disbursed_loans_properties", "Disbursed Loans Properties Tests"),
        
        # Age & Gender Analytics Tests
        ("reports.tests.test_age_gender_analytics_unit", "Age & Gender Analytics Unit Tests"),
        ("reports.test_demographic_properties", "Demographic Properties Tests"),
        
        # Loan Edit Tests
        ("loans.test_loan_edit_unit", "Loan Edit Unit Tests"),
        ("loans.test_loan_edit_properties", "Loan Edit Properties Tests"),
        
        # Penalty Addition Tests
        ("loans.test_penalty_unit", "Penalty Addition Unit Tests"),
        ("loans.test_penalty_properties", "Penalty Properties Tests"),
        
        # Overdue Status Tests
        ("loans.test_overdue_unit", "Overdue Status Unit Tests"),
        ("loans.test_overdue_properties", "Overdue Properties Tests"),
        
        # Date Filtering Tests
        ("reports.test_date_filtering_unit", "Date Filtering Unit Tests"),
        ("reports.test_date_filtering_properties", "Date Filtering Properties Tests"),
        
        # Export Tests
        ("reports.test_export_unit", "Export Unit Tests"),
        ("reports.test_export_properties", "Export Properties Tests"),
        
        # Calculation Tests
        ("loans.test_calculation_properties", "Calculation Properties Tests"),
        
        # Recalculation Tests
        ("loans.test_recalculation_unit", "Recalculation Unit Tests"),
        ("loans.test_recalculation_properties", "Recalculation Properties Tests"),
        
        # Security Tests
        ("loans.test_security_unit", "Security Unit Tests"),
        ("loans.test_validation_security_properties", "Validation & Security Properties Tests"),
    ]
    
    print_header("PHASE 1: UNIT TESTS")
    
    unit_test_modules = [m for m in test_modules if "unit" in m[0].lower()]
    
    for module, description in unit_test_modules:
        success = run_command(
            f"python manage.py test {module} --verbosity=2",
            description
        )
        results[description] = "✅ PASSED" if success else "❌ FAILED"
    
    print_header("PHASE 2: PROPERTY-BASED TESTS")
    
    property_test_modules = [m for m in test_modules if "properties" in m[0].lower()]
    
    for module, description in property_test_modules:
        success = run_command(
            f"python manage.py test {module} --verbosity=2",
            description
        )
        results[description] = "✅ PASSED" if success else "❌ FAILED"
    
    print_header("PHASE 3: CODE COVERAGE ANALYSIS")
    
    # Run coverage for modified modules
    coverage_modules = [
        "loans.models",
        "loans.views",
        "loans.signals",
        "loans.validators",
        "loans.sanitizers",
        "loans.decorators",
        "reports.comprehensive_reports",
        "reports.demographic_service",
        "reports.export_service",
        "reports.age_gender_analytics_view",
    ]
    
    coverage_source = ",".join(coverage_modules)
    
    print("\n🔍 Running coverage analysis...")
    print(f"Modules: {coverage_source}\n")
    
    # Run all tests with coverage
    all_modules = " ".join([m[0] for m in test_modules])
    coverage_success = run_command(
        f"coverage run --source={coverage_source} manage.py test {all_modules}",
        "Coverage Analysis"
    )
    
    if coverage_success:
        # Generate coverage report
        print("\n📊 Coverage Report:\n")
        subprocess.run("coverage report", shell=True)
        
        # Generate HTML coverage report
        print("\n📄 Generating HTML coverage report...")
        subprocess.run("coverage html", shell=True)
        print("HTML report generated in htmlcov/index.html")
    
    results["Coverage Analysis"] = "✅ COMPLETED" if coverage_success else "❌ FAILED"
    
    # Print summary
    print_header("TEST SUITE SUMMARY")
    
    passed = sum(1 for v in results.values() if "✅" in v)
    failed = sum(1 for v in results.values() if "❌" in v)
    total = len(results)
    
    for test_name, status in results.items():
        print(f"{status} {test_name}")
    
    print(f"\n📊 Results: {passed}/{total} passed, {failed}/{total} failed")
    
    if failed == 0:
        print("\n✅ ALL TESTS PASSED! Ready for deployment.")
        return 0
    else:
        print("\n❌ SOME TESTS FAILED. Please review and fix failing tests.")
        return 1

if __name__ == "__main__":
    sys.exit(main())
