import os

import pytest


def _is_rate_limit_error(excinfo, report=None) -> bool:
    """Check if an exception indicates a rate limit error from GitHub API.

    Args:
        excinfo: The exception info from pytest
        report: Optional test report for additional context (captured output, longrepr)
    """
    if excinfo is None:
        return False

    exc = excinfo.value
    exc_type = excinfo.typename
    exc_str = str(exc).lower()

    # BrokenResourceError typically indicates connection closed due to rate limit
    if exc_type == "BrokenResourceError":
        return True

    # httpx.HTTPStatusError with 429 status
    if exc_type == "HTTPStatusError":
        try:
            if hasattr(exc, "response") and exc.response.status_code == 429:
                return True
        except Exception:
            pass

    # Check for rate limit indicators in exception message
    if "429" in exc_str or "rate limit" in exc_str or "too many requests" in exc_str:
        return True

    # Timeout exceptions may indicate rate limiting when the 429 causes asyncio
    # shutdown issues. Check if it's a timeout and look for 429 in the captured output.
    if "timeout" in exc_type.lower() or "timeout" in exc_str:
        # Check captured output for 429 indicators
        if report is not None:
            longrepr_str = str(report.longrepr).lower() if report.longrepr else ""
            if "429" in longrepr_str or "too many requests" in longrepr_str:
                return True

            # Check captured stdout/stderr
            for section_name, content in getattr(report, "sections", []):
                if "429" in content or "too many requests" in content.lower():
                    return True

    return False


@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
    """Convert rate limit failures to skips for GitHub integration tests."""
    outcome = yield
    report = outcome.get_result()

    # Only process actual failures during the call phase, not xfails
    if (
        report.when == "call"
        and report.failed
        and not hasattr(report, "wasxfail")
        and item.module.__name__ == "tests.integration_tests.test_github_mcp_remote"
        and _is_rate_limit_error(call.excinfo, report)
    ):
        report.outcome = "skipped"
        report.longrepr = (
            os.path.abspath(__file__),
            None,
            "Skipped: Skipping due to GitHub API rate limit (429)",
        )
