"""Tests for ievo learn subcommands."""

from __future__ import annotations

from pathlib import Path
from unittest.mock import patch

from ievo.commands.learn import log, push, status


def test_log_no_file(tmp_project_with_agent: Path) -> None:
    root = tmp_project_with_agent
    # Remove the evo log
    evo_log = root / "agents" / "spec-writer" / "EVOLUTION_LOG.md"
    evo_log.unlink()

    with patch("ievo.commands.learn.require_project", return_value=root):
        log(agent="spec-writer", last=0)  # should not raise


def test_log_empty_log(tmp_project_with_agent: Path) -> None:
    root = tmp_project_with_agent

    with patch("ievo.commands.learn.require_project", return_value=root):
        log(agent="spec-writer", last=0)  # "hasn't evolved yet"


def test_log_with_entries(tmp_project_with_agent: Path) -> None:
    root = tmp_project_with_agent
    evo_log = root / "agents" / "spec-writer" / "EVOLUTION_LOG.md"
    evo_log.write_text(
        "# Evolution Log\n\n"
        "## E-001: Fixed prompt\n\nDetails here.\n\n"
        "## E-002: Better memory\n\nMore details.\n"
    )

    with patch("ievo.commands.learn.require_project", return_value=root):
        log(agent="spec-writer", last=0)  # show all
        log(agent="spec-writer", last=1)  # show last 1


def test_status_single_agent(tmp_project_with_agent: Path) -> None:
    root = tmp_project_with_agent

    with patch("ievo.commands.learn.require_project", return_value=root):
        status(agent="spec-writer")  # should not raise


def test_status_all_agents(tmp_project_with_agent: Path) -> None:
    root = tmp_project_with_agent

    with patch("ievo.commands.learn.require_project", return_value=root):
        status(agent=None)  # should not raise


def test_push_no_data(tmp_project_with_agent: Path) -> None:
    root = tmp_project_with_agent

    with patch("ievo.commands.learn.require_project", return_value=root):
        push(agent="spec-writer")  # "no evolution data to push"


def test_push_with_data(tmp_project_with_agent: Path) -> None:
    root = tmp_project_with_agent
    evo_log = root / "agents" / "spec-writer" / "EVOLUTION_LOG.md"
    evo_log.write_text("# Evolution Log\n\n## E-001: Fixed prompt\n\nDetails here.\n")

    with patch("ievo.commands.learn.require_project", return_value=root):
        push(agent="spec-writer")  # should push (anonymized)


def test_push_all_agents(tmp_project_with_agent: Path) -> None:
    root = tmp_project_with_agent
    evo_log = root / "agents" / "spec-writer" / "EVOLUTION_LOG.md"
    evo_log.write_text("# Evolution Log\n\n## E-001: Fixed prompt\n\nDetails here.\n")

    with patch("ievo.commands.learn.require_project", return_value=root):
        push(agent=None)  # push all agents


# ── Branch partial coverage ─────────────────────────────────


def test_status_missing_evo_log_and_role(tmp_project_with_agent: Path) -> None:
    """Status works when evo log and ROLE.md don't exist."""
    root = tmp_project_with_agent
    (root / "agents" / "spec-writer" / "EVOLUTION_LOG.md").unlink()
    (root / "agents" / "spec-writer" / "ROLE.md").unlink()

    with patch("ievo.commands.learn.require_project", return_value=root):
        status(agent="spec-writer")


# ── Deprecation warnings ────────────────────────────────────


def test_log_shows_deprecation_warning(tmp_project_with_agent: Path) -> None:
    root = tmp_project_with_agent

    with (
        patch("ievo.commands.learn.require_project", return_value=root),
        patch("ievo.utils.deprecation.warn") as mock_warn,
    ):
        log(agent="spec-writer", last=0)

    mock_warn.assert_called_once()
    assert "deprecated" in mock_warn.call_args[0][0]


def test_push_shows_deprecation_warning(tmp_project_with_agent: Path) -> None:
    root = tmp_project_with_agent

    with (
        patch("ievo.commands.learn.require_project", return_value=root),
        patch("ievo.utils.deprecation.warn") as mock_warn,
    ):
        push(agent="spec-writer")

    mock_warn.assert_called_once()
    assert "deprecated" in mock_warn.call_args[0][0]


def test_status_shows_deprecation_warning(tmp_project_with_agent: Path) -> None:
    root = tmp_project_with_agent

    with (
        patch("ievo.commands.learn.require_project", return_value=root),
        patch("ievo.utils.deprecation.warn") as mock_warn,
    ):
        status(agent="spec-writer")

    mock_warn.assert_called_once()
    assert "deprecated" in mock_warn.call_args[0][0]
