"""Test comment truncation functionality."""

import pytest

from iam_validator.core.models import PolicyValidationResult, ValidationIssue
from iam_validator.core.report import ReportGenerator


def create_test_issue(severity: str, index: int) -> ValidationIssue:
    """Create a test validation issue."""
    return ValidationIssue(
        severity=severity,
        issue_type="TEST_ISSUE",
        message=f"This is a test issue number {index} with some details about what went wrong.",
        statement_index=index,
        action=f"s3:GetObject{index}",
        resource=f"arn:aws:s3:::bucket-{index}/*",
        suggestion=f"Consider fixing this issue by doing XYZ for statement {index}.",
    )


def create_test_result(policy_file: str, num_issues: int) -> PolicyValidationResult:
    """Create a test validation result."""
    issues = [create_test_issue("error" if i % 2 == 0 else "warning", i) for i in range(num_issues)]
    return PolicyValidationResult(
        policy_file=policy_file,
        is_valid=False,
        issues=issues,
    )


def test_small_report_not_truncated():
    """Test that small reports are not truncated."""
    generator = ReportGenerator()

    # Create a small report
    results = [create_test_result(f"policy-{i}.json", 3) for i in range(5)]
    report = generator.generate_report(results)

    # Generate comment
    comment = generator.generate_github_comment(report)

    # Verify no truncation warning
    assert "Output Truncated" not in comment
    assert "⚠️" not in comment or "Total Issues Found" in comment  # Emoji is in summary
    assert len(comment) < 65000


def test_large_report_is_truncated():
    """Test that large reports are properly truncated."""
    generator = ReportGenerator()

    # Create a large report that will exceed the limit
    results = [create_test_result(f"policy-{i}.json", 20) for i in range(100)]
    report = generator.generate_report(results)

    # Generate comment with a small limit to force truncation
    comment = generator.generate_github_comment(report, max_length=5000)

    # Verify truncation warning is present
    assert "Output Truncated" in comment
    assert "Showing:" in comment
    assert "Remaining:" in comment
    assert "Tip:" in comment
    assert len(comment) <= 5100  # Allow small buffer for calculation differences


def test_truncation_prioritizes_errors():
    """Test that truncation prioritizes showing errors over warnings."""
    generator = ReportGenerator()

    # Create results with errors first, then warnings
    results = []
    # Add policies with errors
    for i in range(10):
        issues = [create_test_issue("error", j) for j in range(5)]
        results.append(
            PolicyValidationResult(
                policy_file=f"error-policy-{i}.json", is_valid=False, issues=issues
            )
        )

    # Add policies with only warnings
    for i in range(10):
        issues = [create_test_issue("warning", j) for j in range(5)]
        results.append(
            PolicyValidationResult(
                policy_file=f"warning-policy-{i}.json", is_valid=False, issues=issues
            )
        )

    report = generator.generate_report(results)

    # Generate comment with limited space
    comment = generator.generate_github_comment(report, max_length=10000)

    # Verify that error policies appear before being truncated
    # Count how many error policies appear vs warning policies
    error_policy_count = comment.count("error-policy-")
    warning_policy_count = comment.count("warning-policy-")

    # Errors should be prioritized
    if "Output Truncated" in comment:
        assert error_policy_count >= warning_policy_count


def test_comment_always_includes_header_and_footer():
    """Test that header and footer are always included even when truncated."""
    generator = ReportGenerator()

    # Create a large report
    results = [create_test_result(f"policy-{i}.json", 20) for i in range(100)]
    report = generator.generate_report(results)

    # Generate comment with small limit
    comment = generator.generate_github_comment(report, max_length=3000)

    # Verify header elements
    assert "IAM Policy Validation Failed" in comment
    assert "Summary" in comment
    assert "Total Policies Analyzed" in comment

    # Verify footer elements
    assert "Generated by IAM Policy Validator" in comment
    assert "Powered by AWS IAM Access Analyzer" in comment


def test_empty_report():
    """Test that empty report (all valid) works correctly."""
    generator = ReportGenerator()

    results = [PolicyValidationResult(policy_file="valid-policy.json", is_valid=True, issues=[])]
    report = generator.generate_report(results)

    comment = generator.generate_github_comment(report)

    assert "All Policies Valid" in comment
    assert "Output Truncated" not in comment
    assert "🎉" in comment  # Success emoji


def test_character_count_accuracy():
    """Test that the character count is accurate and respects the limit."""
    generator = ReportGenerator()

    # Create a large report
    results = [create_test_result(f"policy-{i}.json", 10) for i in range(50)]
    report = generator.generate_report(results)

    # Test with various limits
    for limit in [5000, 10000, 20000, 65000]:
        comment = generator.generate_github_comment(report, max_length=limit)
        actual_length = len(comment)

        # Allow 5% buffer for calculation differences
        max_allowed = limit * 1.05

        assert actual_length <= max_allowed, (
            f"Comment length {actual_length} exceeds limit {limit} (with 5% buffer: {max_allowed})"
        )


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