"""Deterministické kontroly injektáže přes procesy v `src/`.

Proč tento soubor existuje: 5. 10. 2026 spustil `agent-audit` (arXiv:2603.22853)
a reportoval 4 CRITICAL findings „LangChain Tool Input Not Sanitized“ na
`model_layer/ollama_client.py` a `llama_cpp_client.py`. Ty jsou **falešné
pozitivy** — v těchto souborech není ani `@tool`, ani `langchain`:

    grep -nE "@tool|langchain" src/cyberbrain26/model_layer/ollama_client.py
    # (prázdné)

Jeho vlastní pravidlo `AGENT-034` pak u 7 míst s `subprocess.run` tvrdilo
„chybí validace vstupu“, což je formálně pravda a prakticky bez dopadu — všechna
volání jsou list argv s konstantními flagy.

Co z toho plyne: `agent-audit` má jinou hranici než tahle. Jeho nálezy jsou
podklad k triage, ne náhrada kontroly. Kontrola, která je tady, je **deterministická
a úplná**: kontroluje přesně tu vlastnost, která injektáži umožňuje, místo toho,
aby hádala její strukturu.
"""

from __future__ import annotations

import re
from pathlib import Path

import pytest

SRC = Path(__file__).resolve().parents[1] / "src" / "cyberbrain26"


def _python_sources() -> list[Path]:
    if not SRC.is_dir():
        pytest.fail(
            f"{SRC} neexistuje — sada by neprošla ani jednou iterací a test by "
            "vypadal jako zelený, aniž by cokoli ověřil"
        )
    files = sorted(SRC.rglob("*.py"))
    assert files, f"{SRC} neobsahuje žádný '*.py' — vakuová kontrola"
    return files


def _lines(files: list[Path], pattern: re.Pattern[str]) -> list[str]:
    """Vrať `soubor:řádek` pro každý výskyt. Prázdný seznam = čisté."""
    hits: list[str] = []
    for path in files:
        text = path.read_text(encoding="utf-8")
        for number, line in enumerate(text.splitlines(), start=1):
            if pattern.search(line):
                hits.append(f"{path.relative_to(SRC.parent.parent)}:{number}")
    return hits


def test_no_shell_true_anywhere() -> None:
    """`subprocess` nesmí nikde používat `shell=True`.

    `shell=True` je jediné, co z proměnné udělá příkaz: bez něj je každý prvek
    listu předaný jako jeden argv element a metacharaktery v hodnotě nejsou
    interpretovány. To je vlastnost, která injektázi přes proces umožňuje, a
    proto se kontroluje přímo místo odhadování tvaru volání.

    V repozitáři je 14 call-siteů `subprocess` a všechny jsou list argv. Tento
    test existuje, aby to zůstalo tak.
    """
    hits = _lines(_python_sources(), re.compile(r"\bshell\s*=\s*True"))
    assert not hits, (
        "subprocess s shell=True — argumenty se interpretují jako příkaz, "
        f"ne jako hodnoty: {hits}. Použij list argv, viz "
        "execution_plane/bubblewrap_provider.py pro referenční tvar."
    )


def test_no_dynamic_process_evaluation() -> None:
    """`os.system`, `eval` a `exec` jsou v `src/` zakázané.

    Všechny tři vykonají řetězec kódem. `eval`/`exec` navíc nejsou v tomto
    kódu potřeba — deklarativní JSON/YAML se načítá přes `json.loads`.
    """
    hits = _lines(
        _python_sources(),
        re.compile(r"\bos\.system\(|\beval\(|\bexec\("),
    )
    assert not hits, f"dynamické vykonávání kódu nalezeno: {hits}"


def test_subprocess_calls_exist_so_the_guard_above_is_not_vacuous() -> None:
    """Kontrola výše nesmí hlídat nulu.

    Bez tohoto testu by `test_no_shell_true_anywhere` prošla i v repu, kde by
    neexistoval ani jeden `subprocess` call — tedy by hlídala vlastnost, která
    je triviálně pravdivá a proti níž je nic chráněno. Je to V2 z
    `.kilo/context/LESSONS_AND_DECISIONS.md`: predikát, který zruší tvrzení,
    takže pak vypadá jako běžící.
    """
    hits = _lines(_python_sources(), re.compile(r"\bsubprocess\."))
    assert hits, (
        "v src/ není žádný subprocess call-site — test_no_shell_true_anywhere "
        "by pak hlídala triviálně pravdivou vlastnost. Buď je refaktoroval "
        "někdo, nebo je zdrojová cesta jiná; obě je třeba promyslet, ne přehlédnout."
    )