"""SkillRegistry 单元测试"""

import pytest

from agentkit.core.exceptions import SkillNotFoundError
from agentkit.skills.base import SkillConfig, Skill
from agentkit.skills.registry import SkillRegistry


def _make_skill(name: str = "test_skill") -> Skill:
    config = SkillConfig.from_dict({
        "name": name,
        "agent_type": "test",
        "task_mode": "llm_generate",
        "prompt": {"identity": f"测试技能 {name}"},
    })
    return Skill(config)


class TestSkillRegistry:
    """SkillRegistry 注册中心测试"""

    def test_register_registers_skill(self):
        registry = SkillRegistry()
        skill = _make_skill("skill_a")
        registry.register(skill)
        assert registry.has_skill("skill_a")

    def test_unregister_removes_skill(self):
        registry = SkillRegistry()
        skill = _make_skill("skill_b")
        registry.register(skill)
        registry.unregister("skill_b")
        assert not registry.has_skill("skill_b")

    def test_get_by_name_returns_skill(self):
        registry = SkillRegistry()
        skill = _make_skill("skill_c")
        registry.register(skill)
        result = registry.get("skill_c")
        assert result is skill

    def test_get_nonexistent_raises_skill_not_found_error(self):
        registry = SkillRegistry()
        with pytest.raises(SkillNotFoundError):
            registry.get("nonexistent")

    def test_list_skills_returns_all_registered(self):
        registry = SkillRegistry()
        registry.register(_make_skill("s1"))
        registry.register(_make_skill("s2"))
        registry.register(_make_skill("s3"))
        skills = registry.list_skills()
        names = [s.name for s in skills]
        assert "s1" in names
        assert "s2" in names
        assert "s3" in names

    def test_list_skills_empty_registry(self):
        registry = SkillRegistry()
        assert registry.list_skills() == []

    def test_update_skill_updates_config(self):
        registry = SkillRegistry()
        skill = _make_skill("updatable")
        registry.register(skill)

        new_config = SkillConfig.from_dict({
            "name": "updatable",
            "agent_type": "updated_type",
            "task_mode": "llm_generate",
            "prompt": {"identity": "更新后的技能"},
            "execution_mode": "direct",
        })
        updated = registry.update_skill("updatable", new_config)
        assert updated.config.agent_type == "updated_type"
        assert updated.config.execution_mode == "direct"

    def test_update_nonexistent_skill_raises_error(self):
        registry = SkillRegistry()
        new_config = SkillConfig.from_dict({
            "name": "ghost",
            "agent_type": "ghost_type",
            "task_mode": "llm_generate",
            "prompt": {"identity": "幽灵"},
        })
        with pytest.raises(SkillNotFoundError):
            registry.update_skill("ghost", new_config)

    def test_has_skill_returns_true(self):
        registry = SkillRegistry()
        registry.register(_make_skill("exists"))
        assert registry.has_skill("exists") is True

    def test_has_skill_returns_false(self):
        registry = SkillRegistry()
        assert registry.has_skill("nope") is False

    def test_duplicate_registration_overwrites_old(self):
        registry = SkillRegistry()
        skill_v1 = _make_skill("dup")
        registry.register(skill_v1)

        # 用新 config 创建同名 skill
        new_config = SkillConfig.from_dict({
            "name": "dup",
            "agent_type": "v2_type",
            "task_mode": "llm_generate",
            "prompt": {"identity": "V2"},
        })
        skill_v2 = Skill(new_config)
        registry.register(skill_v2)

        result = registry.get("dup")
        assert result.config.agent_type == "v2_type"

    def test_unregister_nonexistent_no_error(self):
        registry = SkillRegistry()
        registry.unregister("nonexistent")  # 不应抛异常
