from __future__ import annotations

from pathlib import Path

import pytest

from ablate.errors import AblateError
from ablate.init import detect_config_file, detect_test_command, run_init


def test_detect_test_command_pytest(tmp_path: Path):
    (tmp_path / "pyproject.toml").write_text("[project]\nname='x'\n")
    assert detect_test_command(tmp_path) == "uv run pytest -q"


def test_detect_test_command_npm(tmp_path: Path):
    (tmp_path / "package.json").write_text("{}")
    assert detect_test_command(tmp_path) == "npm test"


def test_detect_test_command_none(tmp_path: Path):
    assert detect_test_command(tmp_path) is None


def test_detect_config_file_prefers_claude_md(tmp_path: Path):
    (tmp_path / "CLAUDE.md").write_text("x")
    (tmp_path / "AGENTS.md").write_text("x")
    assert detect_config_file(tmp_path) == "CLAUDE.md"


def test_detect_config_file_none(tmp_path: Path):
    assert detect_config_file(tmp_path) is None


def test_run_init_writes_three_tasks(tmp_path: Path):
    (tmp_path / "pyproject.toml").write_text("[project]\nname='x'\n")
    (tmp_path / "CLAUDE.md").write_text("# conventions\n")

    test_cmd, config_file, written, skipped = run_init(tmp_path)

    assert test_cmd == "uv run pytest -q"
    assert config_file == "CLAUDE.md"
    assert len(written) == 3
    assert skipped == []
    for p in written:
        assert p.exists()
        assert "TODO" in p.read_text()


def test_run_init_never_overwrites_a_hand_written_task(tmp_path: Path):
    """Guards against silent loss of a hand-written suite.

    `run_init` used to write unconditionally, so a second `ablate init` -- run
    to re-check detection, or out of habit -- replaced real tasks with TODO
    stubs and said nothing. The suite is the most expensive thing a user of
    this tool produces.
    """
    (tmp_path / "pyproject.toml").write_text("[project]\nname='x'\n")
    run_init(tmp_path)

    mine = tmp_path / ".ablate" / "tasks" / "restraint.yaml"
    mine.write_text("id: restraint\nprompt: my real task\nassert: []\n")

    _, _, written, skipped = run_init(tmp_path)

    assert mine.read_text() == "id: restraint\nprompt: my real task\nassert: []\n"
    assert mine in skipped
    assert mine not in written


def test_run_init_raises_when_no_test_command_detected(tmp_path: Path):
    with pytest.raises(AblateError):
        run_init(tmp_path)


def test_run_init_tasks_are_loadable(tmp_path: Path):
    """The templates run_init writes must themselves satisfy the Task schema
    once the TODOs are filled -- catch a schema/template drift immediately."""
    from ablate.task import load_tasks

    (tmp_path / "pyproject.toml").write_text("[project]\nname='x'\n")
    run_init(tmp_path)

    tasks = load_tasks(tmp_path / ".ablate" / "tasks")
    assert {t.id for t in tasks} == {"bug-fix", "convention-adherence", "restraint"}
