"""Tests for timmy.tool_safety — classification, extraction, and formatting."""

import pytest

from timmy.tool_safety import (
    extract_tool_calls,
    format_action_description,
    get_impact_level,
    requires_confirmation,
)

# ---------------------------------------------------------------------------
# requires_confirmation
# ---------------------------------------------------------------------------


class TestRequiresConfirmation:
    def test_dangerous_tools(self):
        for tool in ("shell", "python", "write_file", "aider", "plan_and_execute"):
            assert requires_confirmation(tool) is True

    def test_safe_tools(self):
        for tool in ("web_search", "calculator", "read_file", "list_files"):
            assert requires_confirmation(tool) is False

    def test_unknown_defaults_to_dangerous(self):
        assert requires_confirmation("totally_unknown") is True


# ---------------------------------------------------------------------------
# extract_tool_calls
# ---------------------------------------------------------------------------


class TestExtractToolCalls:
    def test_arguments_format(self):
        text = (
            'Creating dir. {"name": "shell", "arguments": {"args": ["mkdir", "-p", "/tmp/test"]}}'
        )
        calls = extract_tool_calls(text)
        assert len(calls) == 1
        assert calls[0][0] == "shell"
        assert calls[0][1]["args"] == ["mkdir", "-p", "/tmp/test"]

    def test_parameters_format(self):
        text = 'Result: {"name": "python", "parameters": {"code": "print(1+1)"}}'
        calls = extract_tool_calls(text)
        assert len(calls) == 1
        assert calls[0][0] == "python"

    def test_multiple_calls(self):
        text = (
            'Step 1: {"name": "shell", "arguments": {"args": ["mkdir", "/tmp/a"]}} '
            'Step 2: {"name": "write_file", "arguments": {"file_name": "/tmp/a/f.md", "contents": "hi"}}'
        )
        calls = extract_tool_calls(text)
        assert len(calls) == 2

    def test_empty_and_none(self):
        assert extract_tool_calls("") == []
        assert extract_tool_calls(None) == []
        assert extract_tool_calls("Just normal text.") == []

    def test_malformed_json(self):
        text = '{"name": "shell", "arguments": {not valid json}}'
        assert extract_tool_calls(text) == []


# ---------------------------------------------------------------------------
# format_action_description
# ---------------------------------------------------------------------------


class TestFormatActionDescription:
    def test_shell_command(self):
        desc = format_action_description("shell", {"command": "ls -la /tmp"})
        assert "ls -la /tmp" in desc

    def test_shell_args_list(self):
        desc = format_action_description("shell", {"args": ["mkdir", "-p", "/tmp/t"]})
        assert "mkdir -p /tmp/t" in desc

    def test_write_file(self):
        desc = format_action_description(
            "write_file", {"file_name": "/tmp/f.md", "contents": "hello world"}
        )
        assert "/tmp/f.md" in desc
        assert "11 chars" in desc

    def test_python(self):
        desc = format_action_description("python", {"code": "print(42)"})
        assert "print(42)" in desc

    def test_unknown_tool(self):
        desc = format_action_description("custom_tool", {"key": "value"})
        assert "custom_tool" in desc


# ---------------------------------------------------------------------------
# get_impact_level
# ---------------------------------------------------------------------------


class TestGetImpactLevel:
    def test_high(self):
        assert get_impact_level("shell") == "high"
        assert get_impact_level("python") == "high"

    def test_medium(self):
        assert get_impact_level("write_file") == "medium"
        assert get_impact_level("aider") == "medium"

    def test_low(self):
        assert get_impact_level("web_search") == "low"
        assert get_impact_level("unknown") == "low"
