"""`chekan task set --deps` — единственная ручка, которой можно связать таски задним числом.

Дефект с натуры: гейт G3 научился видеть зоны из нескольких путей и справедливо
кричит, что два таска делят зону без связи зависимостью, а `chekan task set` умел
менять только `--verify`, `--zone`, `--title` и `--model` — записать саму связь
было нечем. `task add` для новой задачи `--deps` уже умеет; здесь та же ручка
для уже существующей.
"""

from __future__ import annotations

import subprocess
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

from test_core import repo, run  # noqa: E402,F401 — общие фикстуры

from chekan.store import Run  # noqa: E402

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


def ceh(root: Path, *args: str) -> subprocess.CompletedProcess:
    return subprocess.run(
        [sys.executable, "-m", "chekan", *args],
        cwd=root, capture_output=True, text=True,
        env={"PYTHONPATH": str(ROOT), "PATH": "/usr/bin:/bin", "HOME": str(root)},
    )


def deps_of(run: Run, tid: str) -> list[str]:
    """Зависимости читаются с диска: у CLI был свой процесс, объект их не видит."""
    return Run(run.root, run.slug).task(tid).get("deps") or []


def three_tasks(run: Run) -> None:
    run.add_requirement("R01", "цитата", note="причина")
    run.add_task("11", "Первая", ["R01"])
    run.add_task("12", "Вторая", ["R01"])
    run.add_task("13", "Третья", ["R01"])


# --- запись связи ---


def test_set_deps_records_the_dependency(run: Run):  # noqa: F811
    three_tasks(run)
    proc = ceh(run.root, "task", "set", "12", "--deps", "11")
    assert proc.returncode == 0, proc.stderr
    assert deps_of(run, "12") == ["11"]


def test_set_deps_accepts_several_values(run: Run):  # noqa: F811
    three_tasks(run)
    proc = ceh(run.root, "task", "set", "13", "--deps", "11", "12")
    assert proc.returncode == 0, proc.stderr
    assert deps_of(run, "13") == ["11", "12"]


def test_empty_deps_clears_them(run: Run):  # noqa: F811
    three_tasks(run)
    assert ceh(run.root, "task", "set", "12", "--deps", "11").returncode == 0
    assert deps_of(run, "12") == ["11"]

    proc = ceh(run.root, "task", "set", "12", "--deps")
    assert proc.returncode == 0, proc.stderr
    assert deps_of(run, "12") == []


def test_deps_is_now_a_valid_thing_to_change(run: Run):  # noqa: F811
    """«Нечего менять» больше не врёт: deps — валидное поле."""
    three_tasks(run)
    proc = ceh(run.root, "task", "set", "12")
    assert proc.returncode != 0
    assert "deps" in proc.stderr, proc.stderr


# --- отказы ---


def test_dependency_on_a_nonexistent_task_is_refused(run: Run):  # noqa: F811
    three_tasks(run)
    proc = ceh(run.root, "task", "set", "12", "--deps", "99")
    assert proc.returncode != 0
    assert "99" in proc.stderr, proc.stderr
    assert deps_of(run, "12") == []


def test_self_dependency_is_refused(run: Run):  # noqa: F811
    three_tasks(run)
    proc = ceh(run.root, "task", "set", "11", "--deps", "11")
    assert proc.returncode != 0, proc.stdout
    assert deps_of(run, "11") == []


def test_a_cycle_is_refused(run: Run):  # noqa: F811
    three_tasks(run)
    assert ceh(run.root, "task", "set", "12", "--deps", "11").returncode == 0
    assert ceh(run.root, "task", "set", "11", "--deps", "12").returncode != 0
    # Состояние не тронуто половинчато: цикл не проехал ни в одну сторону.
    assert deps_of(run, "11") == []
    assert deps_of(run, "12") == ["11"]
