"""Tests for tsumugi.tools module."""

import os
from pathlib import Path

import pytest

from tsumugi.tools import ToolRegistry, create_default_registry
from tsumugi.tools.base import BaseTool, PermissionLevel, ToolSpec


class TestToolRegistry:
    def test_create_default_registry(self):
        registry = create_default_registry()
        assert len(registry.names) == 8

    def test_expected_tools_registered(self):
        registry = create_default_registry()
        expected = [
            "read_file", "write_file", "edit_file", "shell",
            "glob_search", "grep_search", "list_directory", "web_fetch",
        ]
        for name in expected:
            assert name in registry.names, f"{name} not registered"

    def test_get_returns_tool(self):
        registry = create_default_registry()
        tool = registry.get("read_file")
        assert tool is not None
        assert isinstance(tool, BaseTool)

    def test_get_unknown_returns_none(self):
        registry = create_default_registry()
        assert registry.get("nonexistent_tool") is None

    def test_to_definitions(self):
        registry = create_default_registry()
        defs = registry.to_definitions()
        assert len(defs) == 8
        names = [d.name for d in defs]
        assert "read_file" in names


class TestReadFile:
    def test_read_existing_file(self, tmp_path):
        f = tmp_path / "hello.txt"
        f.write_text("Hello, world!", encoding="utf-8")
        registry = create_default_registry()
        tool = registry.get("read_file")
        result = tool.execute(file_path=str(f))
        assert "Hello, world!" in result

    def test_read_nonexistent_file(self):
        registry = create_default_registry()
        tool = registry.get("read_file")
        result = tool.execute(file_path="/nonexistent/path/xyz.txt")
        assert "Error" in result or "error" in result.lower()


class TestWriteFile:
    def test_write_new_file(self, tmp_path):
        f = tmp_path / "output.txt"
        registry = create_default_registry()
        tool = registry.get("write_file")
        result = tool.execute(file_path=str(f), content="test content")
        assert f.read_text(encoding="utf-8") == "test content"
        assert "Successfully" in result


class TestEditFile:
    def test_replace_string(self, tmp_path):
        f = tmp_path / "edit_me.txt"
        f.write_text("Hello World\nFoo Bar", encoding="utf-8")
        registry = create_default_registry()
        tool = registry.get("edit_file")
        result = tool.execute(
            file_path=str(f), old_string="Hello World", new_string="Goodbye World"
        )
        content = f.read_text(encoding="utf-8")
        assert "Goodbye World" in content
        assert "Hello World" not in content

    def test_replace_not_found(self, tmp_path):
        f = tmp_path / "edit_me.txt"
        f.write_text("Hello World", encoding="utf-8")
        registry = create_default_registry()
        tool = registry.get("edit_file")
        result = tool.execute(
            file_path=str(f), old_string="NONEXISTENT", new_string="X"
        )
        assert "not found" in result.lower() or "error" in result.lower()


class TestShell:
    def test_echo_command(self):
        registry = create_default_registry()
        tool = registry.get("shell")
        result = tool.execute(command="echo hello_tsumugi")
        assert "hello_tsumugi" in result


class TestGlobSearch:
    def test_find_py_files(self, tmp_path):
        (tmp_path / "a.py").touch()
        (tmp_path / "b.py").touch()
        (tmp_path / "c.txt").touch()
        registry = create_default_registry()
        tool = registry.get("glob_search")
        result = tool.execute(pattern="*.py", path=str(tmp_path))
        assert "a.py" in result
        assert "b.py" in result
        assert "c.txt" not in result


class TestGrepSearch:
    def test_find_pattern(self, tmp_path):
        f = tmp_path / "searchme.py"
        f.write_text("def hello():\n    return 'world'\n", encoding="utf-8")
        registry = create_default_registry()
        tool = registry.get("grep_search")
        result = tool.execute(pattern="def hello", path=str(tmp_path))
        assert "hello" in result

    def test_no_match(self, tmp_path):
        f = tmp_path / "searchme.py"
        f.write_text("nothing here\n", encoding="utf-8")
        registry = create_default_registry()
        tool = registry.get("grep_search")
        result = tool.execute(pattern="ZZZZNOTHERE", path=str(tmp_path))
        assert "0" in result or "No" in result or "no" in result


class TestListDirectory:
    def test_list_contents(self, tmp_path):
        (tmp_path / "file.txt").write_text("hi", encoding="utf-8")
        (tmp_path / "subdir").mkdir()
        registry = create_default_registry()
        tool = registry.get("list_directory")
        result = tool.execute(path=str(tmp_path))
        assert "file.txt" in result
        assert "subdir" in result
        assert "[DIR]" in result
        assert "[FILE]" in result
