from __future__ import annotations

from pathlib import Path

import pytest

from ablate.errors import AblateError
from ablate.task import load_task, load_tasks


def _write(path: Path, content: str) -> Path:
    path.write_text(content)
    return path


VALID = """\
id: fix-null-deref
description: Fix the crash.
prompt: |
  Fix the null dereference in the parser.
assert:
  - id: tests-pass
    type: exit_code
    run: pytest -q
    expect: 0
  - id: no-vendored-deps
    type: files_touched
    must_not_include: ["vendor/**"]
"""


def test_load_task_valid(tmp_path: Path):
    p = _write(tmp_path / "t.yaml", VALID)
    task = load_task(p)
    assert task.id == "fix-null-deref"
    assert len(task.assertions) == 2
    assert task.assertions[0].type == "exit_code"
    assert task.config_path == "CLAUDE.md"  # default


def test_load_task_requires_at_least_one_assertion(tmp_path: Path):
    p = _write(tmp_path / "t.yaml", "id: x\nprompt: hi\nassert: []\n")
    with pytest.raises(AblateError):
        load_task(p)


def test_load_task_invalid_yaml(tmp_path: Path):
    p = _write(tmp_path / "t.yaml", "id: x\n  bad indent: [")
    with pytest.raises(AblateError):
        load_task(p)


def test_load_task_not_a_mapping(tmp_path: Path):
    p = _write(tmp_path / "t.yaml", "- just\n- a\n- list\n")
    with pytest.raises(AblateError):
        load_task(p)


def test_load_tasks_sorted_and_deduped(tmp_path: Path):
    _write(tmp_path / "b.yaml", VALID.replace("fix-null-deref", "bbb"))
    _write(tmp_path / "a.yaml", VALID.replace("fix-null-deref", "aaa"))
    tasks = load_tasks(tmp_path)
    assert [t.id for t in tasks] == ["aaa", "bbb"]


def test_load_tasks_rejects_duplicate_ids(tmp_path: Path):
    _write(tmp_path / "a.yaml", VALID)
    _write(tmp_path / "b.yaml", VALID)
    with pytest.raises(AblateError, match="duplicate task id"):
        load_tasks(tmp_path)


def test_load_tasks_empty_dir_raises(tmp_path: Path):
    with pytest.raises(AblateError):
        load_tasks(tmp_path)
