"""Surface TileLang warnings that pytest would otherwise swallow.

TileLang emits warnings through two channels, both hidden by pytest's capture
unless a test fails or ``-s`` is passed:

1. Python logging.  TileLang sets ``propagate = False`` on its logger
   (``tilelang/__init__.py::_init_logger``), formatted as::

       2026-07-17 10:41:51,361  [TileLang:tilelang.cache:WARNING] (file.py:123): ...

2. The C++/TVM backend.  ``LOG(WARNING)`` prints straight to stderr during
   kernel compilation (``tilelang/src/runtime/logging.cc``)::

       [11:10:57] : Warning: Casting in BufferStore may lose precision: ...

This plugin scans each test's captured output for both, then prints a single
consolidated summary at the end of the session.
"""

import re

# Matches either warning channel; group 1 is the timestamp-independent part
# used both to detect a warning and to de-duplicate repeats.
_WARNING_RE = re.compile(
    r'(\[TileLang:[^\]]*:WARN(?:ING)?\].*|: Warning:.*)',
    re.IGNORECASE,
)

# nodeid -> de-duplicated list of warning lines seen during that test.
_warnings_by_test = {}


def _extract_tilelang_warnings(report):
    """Return de-duplicated TileLang warning lines from a test report."""
    seen = set()
    warnings = []
    for captured in (report.capstdout, report.capstderr):
        for line in (captured or '').splitlines():
            match = _WARNING_RE.search(line)
            # De-duplicate on the timestamp-independent tail so the same
            # warning with different timestamps collapses to one entry.
            if match and match.group(1) not in seen:
                seen.add(match.group(1))
                warnings.append(line)
    return warnings


def pytest_runtest_logreport(report):
    """Collect TileLang warnings from each test's call phase."""
    if report.when != 'call':
        return
    warnings = _extract_tilelang_warnings(report)
    if warnings:
        _warnings_by_test.setdefault(report.nodeid, []).extend(warnings)


def pytest_terminal_summary(terminalreporter, exitstatus, config):
    """Print one consolidated TileLang warnings section at end of session."""
    if not _warnings_by_test:
        return
    total = sum(len(w) for w in _warnings_by_test.values())
    terminalreporter.write_sep('=', 'TileLang warnings summary', yellow=True)
    for nodeid, warnings in _warnings_by_test.items():
        terminalreporter.write_line(nodeid, yellow=True)
        for line in warnings:
            terminalreporter.write_line(f'  {line}', yellow=True)
    terminalreporter.write_line(
        f'{total} TileLang warning(s) across {len(_warnings_by_test)} test(s)',
        yellow=True,
    )