#!/usr/bin/env python3
"""Generate a SPEC marker collection report.

This helper runs ``pytest --collect-only -q`` and filters the collected node IDs
for lines containing ``SPEC-`` (equivalent to piping the output to ``rg "SPEC-"``).
The resulting snapshot is written to ``reports/logs/spec_id_updates`` with a
timestamped filename so Phase7c can track normalization progress.
"""

from __future__ import annotations

import argparse
import datetime as _dt
import subprocess
import sys
from pathlib import Path

LOG_DIR = Path("reports/logs/spec_id_updates")


def _run_pytest_collect(pytest_args: list[str]) -> tuple[int, str]:
    """Run pytest in collect-only mode and return (exit_code, combined_output)."""
    cmd = ["pytest", "--collect-only", "-q", *pytest_args]
    result = subprocess.run(
        cmd,
        capture_output=True,
        text=True,
        check=False,
    )
    combined = (result.stdout or "") + (result.stderr or "")
    return result.returncode, combined


def _filter_spec_lines(stream: str) -> str:
    """Filter lines containing ``SPEC-``.

    Prefer ``rg`` for consistency with manual workflows, but fall back to a
    simple Python filter if ripgrep is unavailable.
    """

    try:
        proc = subprocess.run(
            ["rg", "SPEC-"],
            input=stream,
            text=True,
            capture_output=True,
            check=False,
        )
    except FileNotFoundError:
        filtered = "\n".join(line for line in stream.splitlines() if "SPEC-" in line)
        return filtered + ("\n" if filtered else "")

    if proc.returncode in (0, 1):  # 1 means no matches when using rg
        return proc.stdout

    # Fallback on unexpected error
    filtered = "\n".join(line for line in stream.splitlines() if "SPEC-" in line)
    return filtered + ("\n" if filtered else "")


def _write_report(content: str, prefix: str) -> Path:
    LOG_DIR.mkdir(parents=True, exist_ok=True)
    timestamp = _dt.datetime.now().strftime("%Y%m%d_%H%M%S")
    dest = LOG_DIR / f"{prefix}_{timestamp}.txt"
    dest.write_text(content, encoding="utf-8")
    return dest


def parse_args(argv: list[str]) -> argparse.Namespace:
    parser = argparse.ArgumentParser(
        description="Generate a SPEC marker report by running pytest collect.",
    )
    parser.add_argument(
        "pytest_args",
        nargs=argparse.REMAINDER,
        help="Additional arguments forwarded to pytest (after --).",
    )
    parser.add_argument(
        "--prefix",
        default="spec_markers",
        help="Filename prefix for the generated report (default: spec_markers).",
    )
    return parser.parse_args(argv)


def main(argv: list[str]) -> int:
    args = parse_args(argv)

    pytest_args = args.pytest_args
    if pytest_args and pytest_args[0] == "--":
        pytest_args = pytest_args[1:]

    exit_code, output = _run_pytest_collect(pytest_args)
    filtered = _filter_spec_lines(output)

    header = [
        "# SPEC Marker Collection Report",
        f"Generated: {_dt.datetime.now().isoformat(timespec='seconds')}",
        f"Command: pytest --collect-only -q{' ' + ' '.join(pytest_args) if pytest_args else ''}",
        f"Pytest exit code: {exit_code}",
        "",
    ]
    report_body = "".join(line + "\n" for line in header)
    report_body += filtered if filtered else "(no SPEC markers found)\n"

    path = _write_report(report_body, args.prefix)
    print(f"Report written to {path}")

    if exit_code != 0:
        print(
            "WARNING: pytest --collect-only returned a non-zero exit code. Review the report for potential issues.",
            file=sys.stderr,
        )
        return exit_code

    return 0


if __name__ == "__main__":
    raise SystemExit(main(sys.argv[1:]))
