"""Tests for timmy.tools_delegation — delegate_task and list_swarm_agents.

Agent IDs are now defined in config/agents.yaml, not hardcoded Python.
Tests reference the YAML-defined IDs: orchestrator, researcher, coder,
writer, memory, experimenter.
"""

from timmy.tools_delegation import delegate_task, list_swarm_agents


class TestDelegateTask:
    def test_unknown_agent_returns_error(self):
        result = delegate_task("nonexistent", "do something")
        assert result["success"] is False
        assert "Unknown agent" in result["error"]
        assert result["task_id"] is None

    def test_valid_agent_names_normalised(self):
        # Agent IDs are lowercased; whitespace should be stripped
        result = delegate_task("  Researcher  ", "think about it")
        assert "Unknown agent" not in result.get("error", "")

    def test_invalid_priority_defaults_to_normal(self):
        # Even with bad priority, delegate_task should not crash
        result = delegate_task("coder", "build", priority="ultra")
        assert isinstance(result, dict)

    def test_all_valid_agents_accepted(self):
        # These IDs match config/agents.yaml
        valid_agents = ["orchestrator", "researcher", "coder", "writer", "memory", "experimenter"]
        for agent in valid_agents:
            result = delegate_task(agent, "test task")
            assert "Unknown agent" not in result.get("error", ""), f"{agent} rejected"

    def test_old_agent_names_no_longer_valid(self):
        # Old hardcoded names should not work anymore
        for old_name in ["seer", "forge", "echo", "helm", "quill", "mace"]:
            result = delegate_task(old_name, "test")
            assert result["success"] is False
            assert "Unknown agent" in result["error"]


class TestListSwarmAgents:
    def test_returns_agents_from_yaml(self):
        result = list_swarm_agents()
        assert result["success"] is True
        assert len(result["agents"]) > 0
        agent_names = [a["name"] for a in result["agents"]]
        # These names come from config/agents.yaml
        assert "Seer" in agent_names
        assert "Forge" in agent_names
        assert "Timmy" in agent_names


class TestDelegateToKimi:
    """Tests for delegate_to_kimi() — Timmy's Kimi delegation tool."""

    def test_returns_dict(self, monkeypatch):
        """delegate_to_kimi should always return a dict."""
        import shutil

        monkeypatch.setattr(shutil, "which", lambda x: None)
        from timmy.tools_delegation import delegate_to_kimi

        result = delegate_to_kimi("test task")
        assert isinstance(result, dict)
        assert "success" in result

    def test_kimi_not_found_returns_error(self, monkeypatch):
        """Should handle missing kimi CLI gracefully."""
        import shutil

        monkeypatch.setattr(shutil, "which", lambda x: None)
        from timmy.tools_delegation import delegate_to_kimi

        result = delegate_to_kimi("test task")
        assert result["success"] is False
        assert "not found" in result["error"]

    def test_invalid_workdir_returns_error(self, monkeypatch):
        """Should reject non-existent working directories."""
        import shutil

        monkeypatch.setattr(shutil, "which", lambda x: "/usr/bin/kimi")
        from timmy.tools_delegation import delegate_to_kimi

        result = delegate_to_kimi("test", working_directory="/nonexistent/path")
        assert result["success"] is False
        assert "does not exist" in result["error"]

    def test_timeout_returns_error(self, monkeypatch):
        """Should handle subprocess timeout gracefully."""
        import shutil
        import subprocess

        monkeypatch.setattr(shutil, "which", lambda x: "/usr/bin/kimi")

        def timeout_run(*args, **kwargs):
            raise subprocess.TimeoutExpired(cmd="kimi", timeout=300)

        monkeypatch.setattr(subprocess, "run", timeout_run)
        from timmy.tools_delegation import delegate_to_kimi

        result = delegate_to_kimi("complex task")
        assert result["success"] is False
        assert "timed out" in result["error"].lower()

    def test_successful_delegation(self, monkeypatch):
        """Should capture Kimi's output on success."""
        import shutil
        import subprocess

        monkeypatch.setattr(shutil, "which", lambda x: "/usr/bin/kimi")

        def mock_run(*args, **kwargs):
            return subprocess.CompletedProcess(
                args=args[0] if args else [],
                returncode=0,
                stdout="Fixed the bug in session.py\n\nChanges:\n- Added null check",
                stderr="",
            )

        monkeypatch.setattr(subprocess, "run", mock_run)
        from config import settings
        from timmy.tools_delegation import delegate_to_kimi

        result = delegate_to_kimi("fix session bug", working_directory=settings.repo_root)
        assert result["success"] is True
        assert "Fixed the bug" in result["output"]
        assert result["return_code"] == 0

    def test_default_workdir_uses_repo_root(self, monkeypatch):
        """Empty working_directory should default to settings.repo_root."""
        import shutil
        import subprocess

        calls = []
        monkeypatch.setattr(shutil, "which", lambda x: "/usr/bin/kimi")

        def capture_run(*args, **kwargs):
            calls.append(kwargs.get("cwd", ""))
            return subprocess.CompletedProcess(
                args=args[0] if args else [], returncode=0, stdout="done", stderr=""
            )

        monkeypatch.setattr(subprocess, "run", capture_run)
        from config import settings
        from timmy.tools_delegation import delegate_to_kimi

        delegate_to_kimi("test task")
        assert len(calls) == 1
        assert calls[0] == settings.repo_root
