"""
Test end-to-end analyzer SAFE proof capability.

This test verifies that the analyzer can produce SAFE verdicts
with barrier certificate proofs for validated non-buggy programs.
"""

import pytest
from pathlib import Path

from pyfromscratch.analyzer import Analyzer, AnalysisResult


def test_analyzer_safe_simple_arithmetic():
    """
    Test analyzer produces SAFE verdict for simple arithmetic.
    """
    # Create test file
    test_file = Path("tests/fixtures/safe_simple.py")
    assert test_file.exists()
    
    analyzer = Analyzer(verbose=False, max_paths=100, max_depth=500)
    result = analyzer.analyze_file(test_file)
    
    # Should find SAFE with barrier certificate
    assert result.verdict == "SAFE", f"Expected SAFE, got {result.verdict}: {result.message}"
    assert result.barrier is not None, "SAFE verdict must have barrier certificate"
    assert result.inductiveness is not None, "SAFE verdict must have inductiveness proof"
    assert result.inductiveness.is_inductive, "Barrier must be inductive"


def test_analyzer_safe_bounded_loop():
    """
    Test analyzer produces SAFE verdict for bounded loop with no unsafe operations.
    
    Note: Phase 3 intra-procedural analysis inlines user functions, which may increase
    path count due to loops in inlined functions. Increased max_paths to accommodate.
    """
    test_file = Path("tests/fixtures/safe_sum_loop.py")
    assert test_file.exists()
    
    analyzer = Analyzer(verbose=False, max_paths=200, max_depth=500)
    result = analyzer.analyze_file(test_file)
    
    # Should find SAFE with barrier certificate
    assert result.verdict == "SAFE", f"Expected SAFE, got {result.verdict}: {result.message}"
    assert result.barrier is not None, "SAFE verdict must have barrier certificate"
    assert result.inductiveness is not None, "SAFE verdict must have inductiveness proof"
    assert result.inductiveness.is_inductive, "Barrier must be inductive"
    
    # Verify proof properties
    assert result.inductiveness.init_holds, "Init condition must hold"
    assert result.inductiveness.unsafe_holds, "Unsafe condition must hold (vacuously)"
    assert result.inductiveness.step_holds, "Step condition must hold"


def test_analyzer_safe_proof_has_details():
    """
    Test that SAFE proof includes proper details for human review.
    """
    test_file = Path("tests/fixtures/safe_simple.py")
    
    analyzer = Analyzer(verbose=False, max_paths=100, max_depth=500)
    result = analyzer.analyze_file(test_file)
    
    assert result.verdict == "SAFE"
    
    # Check summary includes key details
    summary = result.summary()
    assert "SAFE" in summary
    assert "barrier" in summary.lower() or "Barrier" in summary
    assert result.barrier.name in summary
    
    # Check barrier has proper attributes
    assert result.barrier.name is not None
    assert result.barrier.epsilon > 0
    assert callable(result.barrier.barrier_fn)


def test_analyzer_safe_vs_bug():
    """
    Test that analyzer correctly identifies SAFE cases.
    
    NOTE: This test currently only validates SAFE detection.
    Bug detection in symbolic execution needs improvement (separate issue).
    
    Phase 3 note: Increased max_paths to accommodate function inlining path expansion.
    """
    # Safe case - should produce SAFE verdict with barrier
    safe_file = Path("tests/fixtures/safe_simple.py")
    analyzer = Analyzer(verbose=False, max_paths=200, max_depth=500)
    safe_result = analyzer.analyze_file(safe_file)
    assert safe_result.verdict == "SAFE"
    assert safe_result.barrier is not None
    
    # Another safe case with loop
    safe_loop = Path("tests/fixtures/safe_sum_loop.py")
    loop_result = analyzer.analyze_file(safe_loop)
    assert loop_result.verdict == "SAFE"
    assert loop_result.barrier is not None


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
