"""Сторож имени (R01, R02, R11i): в репозитории нет упоминаний старого имени.

Разрешена ровно ОДНА строка в README.md — историческая сноска переименования.
Рычаг порчи (добавление старого слова) обязан делать тест красным.
"""

from __future__ import annotations

import os
import re
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent

EXCLUDE_DIRS = {".git", ".venv", "venv", "__pycache__", ".pytest_cache"}
EXCLUDE_FILES = {
    "test_naming.py",
    "modern-screenshot.umd.js",  # вендорная библиотека стороннего скрина
}

_A = "auto" + "ceh"
_R = "авто" + "цех"
PATTERN = re.compile(rf"\b({_A}|{_R})\b", re.IGNORECASE)

ALLOWED_LINE = "21.08.2026 инструмент переименован"


def scan_repo() -> list[tuple[Path, int, str]]:
    """Сканирует весь репозиторий на вхождение старых имён."""
    findings: list[tuple[Path, int, str]] = []
    for root, dirs, files in os.walk(ROOT):
        dirs[:] = [d for d in dirs if d not in EXCLUDE_DIRS]
        for f in files:
            if f in EXCLUDE_FILES or f.endswith(".pyc") or f.endswith(".png") or f.endswith(".b64"):
                continue
            path = Path(root) / f
            try:
                text = path.read_text(encoding="utf-8")
            except (UnicodeDecodeError, OSError):
                continue

            root_str = str(ROOT)
            for lineno, line in enumerate(text.splitlines(), start=1):
                line_clean = line.replace(root_str, "").replace(".config/" + _A, "")
                if PATTERN.search(line_clean):
                    # Единственное разрешенное место: сноска в README.md
                    if path.name == "README.md" and ALLOWED_LINE in line:
                        continue
                    findings.append((path.relative_to(ROOT), lineno, line.strip()))
    return findings


def test_no_old_name_in_repository():
    """В репозитории и архиве прогонов нет старого имени, кроме одной строки в README.md."""
    findings = scan_repo()
    if findings:
        report = "\n".join(f"  {p}:{ln} -> {l}" for p, ln, l in findings)
        raise AssertionError(f"Найдено старое имя ({len(findings)} мест):\n{report}")


def test_naming_guard_catches_corruption(tmp_path: Path):
    """Рычаг порчи: добавление старого имени ломает проверку."""
    target = tmp_path / "probe.txt"
    target.write_text("старый " + _A + " в коде\n", encoding="utf-8")
    assert PATTERN.search(target.read_text(encoding="utf-8")) is not None
