"""ORCH-101 (TC-10, AC-3/AC-4): репликационная документация и smoke-процедура.

Структурные проверки: deployment-док `docs/operations/REPLICATION.md`
существует и несёт пошаговую smoke-процедуру с явными PASS/FAIL-критериями,
карту env-переменных, чек-лист секретов и границы 10-common vs Lite vs
Bundled; карта env в INFRA.md дополнена; CHANGELOG.md содержит запись
ORCH-101; гайд stateless (не предписывает перенос боевых данных/секретов).
Скрипт-обвязка ORCH-101 не вводилась (ADR-001 D9 — чистый runbook), поэтому
запускаемость проверяется только для генератора секретов (--help, без
сети/LLM).
"""

import subprocess
import sys
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parents[1]
REPLICATION = REPO_ROOT / "docs/operations/REPLICATION.md"
INFRA = REPO_ROOT / "docs/operations/INFRA.md"
CHANGELOG = REPO_ROOT / "CHANGELOG.md"


def _replication_text() -> str:
    assert REPLICATION.is_file(), "docs/operations/REPLICATION.md отсутствует (AC-3)"
    return REPLICATION.read_text(encoding="utf-8")


def test_replication_doc_has_smoke_procedure_with_pass_fail():
    text = _replication_text()
    # Каждый шаг smoke имеет явный критерий; маркеры вердикта присутствуют.
    assert "PASS" in text and "FAIL" in text
    # Ключевые кирпичи процедуры (D9): health-check, onboarding-CLI, очередь.
    for brick in ("/health", "/queue", "onboard_project.py", "docker compose config"):
        assert brick in text, f"smoke-кирпич {brick} не упомянут в REPLICATION.md"
    # Минимальный сигнал «конвейер доехал»: стадия analysis + артефакты 01–04.
    assert "analysis" in text
    assert "01" in text and "04" in text


def test_replication_doc_covers_secrets_checklist():
    text = _replication_text()
    assert "gen_secrets.py" in text
    for token in (
        "ORCH_PLANE_WEBHOOK_SECRET",
        "ORCH_GITEA_WEBHOOK_SECRET",
        "ORCH_PLANE_API_TOKEN",
        "ORCH_GITEA_TOKEN",
        "ORCH_TELEGRAM_BOT_TOKEN",
    ):
        assert token in text, f"секрет {token} не покрыт чек-листом"
    # Нормативная строка stateless-тиража (AC-5): боевые секреты не копируются.
    assert "не копиру" in text.lower()


def test_replication_doc_has_env_map_and_boundaries():
    text = _replication_text()
    for var in (
        "ORCH_AGENT_HOME_DIR",
        "ORCH_AGENT_GIT_NAME",
        "ORCH_GIT_EMAIL_DOMAIN",
        "ORCH_STAGING_PORT",
        "ORCH_DOCKER_GID",
        "ORCH_RUN_UID",
        "ORCH_HOST_REPOS_DIR",
    ):
        assert var in text, f"переменная {var} отсутствует в карте env REPLICATION.md"
    # Границы тиража (анти-скоуп-крип Р-5) + платформенные конвенции (D3/D4).
    assert "Lite" in text and "Bundled" in text
    assert "orchestrator" in text  # конвенция имени репо платформы
    # Чек-лист обязывает задать реестр проектов на новом хосте (A9).
    assert "ORCH_PROJECTS_JSON" in text


def test_replication_doc_is_stateless():
    text = _replication_text().lower()
    # Процедура не предписывает перенос БД/данных с боевого хоста.
    assert "перенос" not in text or "не предполагает перенос" in text or "без перенос" in text


def test_infra_env_map_extended():
    text = INFRA.read_text(encoding="utf-8")
    for var in ("ORCH_AGENT_HOME_DIR", "ORCH_STAGING_PORT", "ORCH_DOCKER_GID"):
        assert var in text, f"{var} отсутствует в карте env INFRA.md (AC-4)"
    assert "REPLICATION.md" in text  # перекрёстная ссылка на deployment-док


def test_changelog_has_orch_101_entry():
    text = CHANGELOG.read_text(encoding="utf-8")
    assert "ORCH-101" in text


def test_gen_secrets_runs_in_safe_mode():
    """Обвязка запускается без ошибок в безопасном режиме (--help: без сети,
    без LLM, без записи файлов)."""
    r = subprocess.run(
        [sys.executable, str(REPO_ROOT / "scripts/gen_secrets.py"), "--help"],
        capture_output=True, text=True, timeout=30,
    )
    assert r.returncode == 0, r.stderr
