# -*- coding: utf-8 -*-
"""ToolRegistry _tool_source 追溯到测试"""
import pytest
from abyss.tools.registry import ToolRegistry
from abyss.tools.base import Tool


class FakeTool(Tool):
    def __init__(self, name):
        self._name = name
    @property
    def name(self) -> str:
        return self._name
    @property
    def description(self) -> str:
        return "fake"
    @property
    def parameters(self) -> dict:
        return {"type": "object", "properties": {}}
    def execute(self, **kw) -> dict:
        return {"ok": True}


class TestToolSource:
    """工具来源追溯测试"""

    def test_register_with_source(self):
        reg = ToolRegistry()
        reg.register(FakeTool("t1"), source="builtin")
        assert reg.get_source("t1") == "builtin"

    def test_register_without_source(self):
        reg = ToolRegistry()
        reg.register(FakeTool("t1"))
        assert reg.get_source("t1") == "unknown"

    def test_list_by_source(self):
        reg = ToolRegistry()
        reg.register(FakeTool("t1"), source="builtin")
        reg.register(FakeTool("t2"), source="mcp__github")
        reg.register(FakeTool("t3"), source="builtin")

        builtin = reg.list_by_source("builtin")
        assert set(builtin) == {"t1", "t3"}

        mcp = reg.list_by_source("mcp__github")
        assert mcp == ["t2"]

    def test_unregister_removes_source(self):
        reg = ToolRegistry()
        reg.register(FakeTool("t1"), source="builtin")
        reg.unregister("t1")
        assert reg.get_source("t1") is None

    def test_unregister_by_source(self):
        reg = ToolRegistry()
        reg.register(FakeTool("t1"), source="mcp__s1")
        reg.register(FakeTool("t2"), source="mcp__s1")
        reg.register(FakeTool("t3"), source="mcp__s2")

        removed = reg.unregister_by_source("mcp__s1")
        assert removed == 2
        assert "t1" not in reg
        assert "t2" not in reg
        assert "t3" in reg  # 不同源不受影响

    def test_get_source_unknown(self):
        reg = ToolRegistry()
        assert reg.get_source("nonexistent") is None
