"""Tests for tool-specific handlers."""

from terminaluse.lib.utils.output import (
    DefaultOutputHandler,
    OutputHandler,
    RequestHandler,
    TaskOutputHandler,
    TaskRequestHandler,
    default_output_handlers,
    default_request_handlers,
)


class TestTaskRequestHandler:
    """Tests for TaskRequestHandler."""

    def test_implements_protocol(self) -> None:
        """TaskRequestHandler implements RequestHandler protocol."""
        handler = TaskRequestHandler()
        assert isinstance(handler, RequestHandler)

    def test_formats_full_task_request(self) -> None:
        """Formats Task request with all fields."""
        handler = TaskRequestHandler()

        result = handler.format(
            {
                "subagent_type": "Explore",
                "description": "Search for auth patterns",
                "name": "auth-explorer",
                "prompt": "Find all authentication...",
            }
        )

        assert "🤖" in result
        assert "[Explore]" in result
        assert "auth-explorer" in result
        assert "Search for auth patterns" in result
        # Should NOT show the full prompt
        assert "Find all authentication" not in result

    def test_formats_without_name(self) -> None:
        """Formats Task request without optional name."""
        handler = TaskRequestHandler()

        result = handler.format(
            {
                "subagent_type": "Plan",
                "description": "Design the architecture",
            }
        )

        assert "🤖" in result
        assert "[Plan]" in result
        assert "Design the architecture" in result

    def test_formats_without_description(self) -> None:
        """Formats Task request without description."""
        handler = TaskRequestHandler()

        result = handler.format(
            {
                "subagent_type": "general-purpose",
                "name": "helper",
            }
        )

        assert "🤖" in result
        assert "[general-purpose]" in result
        assert "helper" in result

    def test_defaults_subagent_type(self) -> None:
        """Defaults subagent_type to 'agent' when missing."""
        handler = TaskRequestHandler()

        result = handler.format({})

        assert "[agent]" in result

    def test_is_frozen_dataclass(self) -> None:
        """TaskRequestHandler is immutable."""
        handler = TaskRequestHandler()
        # Frozen dataclass should be hashable
        assert hash(handler) is not None


class TestDefaultOutputHandler:
    """Tests for DefaultOutputHandler."""

    def test_implements_protocol(self) -> None:
        """DefaultOutputHandler implements OutputHandler protocol."""
        handler = DefaultOutputHandler()
        assert isinstance(handler, OutputHandler)

    def test_renders_empty_lines(self) -> None:
        """Empty lines show empty marker."""
        handler = DefaultOutputHandler()

        result = handler.render([])

        assert "(empty)" in result
        assert "'-->" in result

    def test_renders_single_line(self) -> None:
        """Single line renders inline."""
        handler = DefaultOutputHandler()

        result = handler.render(["Hello World"])

        assert "'--> Hello World" in result

    def test_renders_multiple_lines(self) -> None:
        """Multiple lines render with arrow prefix."""
        handler = DefaultOutputHandler()

        result = handler.render(["Line 1", "Line 2", "Line 3"])

        assert "'-->" in result
        assert "Line 1" in result
        assert "Line 2" in result
        assert "Line 3" in result

    def test_truncates_when_not_verbose(self) -> None:
        """Truncates lines beyond max_lines."""
        handler = DefaultOutputHandler(max_lines=2, verbose=False)
        lines = [f"line{i}" for i in range(10)]

        result = handler.render(lines)

        assert "line0" in result
        assert "line1" in result
        assert "line9" not in result
        assert "more lines" in result

    def test_shows_all_when_verbose(self) -> None:
        """Verbose mode shows all lines."""
        handler = DefaultOutputHandler(max_lines=2, verbose=True)
        lines = [f"line{i}" for i in range(10)]

        result = handler.render(lines)

        assert "line0" in result
        assert "line9" in result
        assert "more lines" not in result

    def test_is_frozen_dataclass(self) -> None:
        """DefaultOutputHandler is immutable."""
        handler = DefaultOutputHandler()
        assert hash(handler) is not None


class TestTaskOutputHandler:
    """Tests for TaskOutputHandler."""

    def test_implements_protocol(self) -> None:
        """TaskOutputHandler implements OutputHandler protocol."""
        handler = TaskOutputHandler()
        assert isinstance(handler, OutputHandler)

    def test_renders_empty_lines(self) -> None:
        """Empty lines show no response marker."""
        handler = TaskOutputHandler()

        result = handler.render([])

        assert "└─" in result
        assert "no response" in result

    def test_renders_single_line(self) -> None:
        """Single line renders with tree prefix."""
        handler = TaskOutputHandler()

        result = handler.render(["Found 5 files"])

        assert "└─ Found 5 files" in result

    def test_renders_multiple_lines(self) -> None:
        """Multiple lines render with tree prefix."""
        handler = TaskOutputHandler()

        result = handler.render(["Line 1", "Line 2", "Line 3"])

        assert "└─" in result
        assert "Line 1" in result
        assert "Line 2" in result
        assert "Line 3" in result

    def test_truncates_when_not_verbose(self) -> None:
        """Truncates lines beyond max_lines."""
        handler = TaskOutputHandler(max_lines=2, verbose=False)
        lines = [f"line{i}" for i in range(10)]

        result = handler.render(lines)

        assert "line0" in result
        assert "line1" in result
        assert "line9" not in result
        assert "more lines" in result

    def test_shows_all_when_verbose(self) -> None:
        """Verbose mode shows all lines."""
        handler = TaskOutputHandler(max_lines=2, verbose=True)
        lines = [f"line{i}" for i in range(10)]

        result = handler.render(lines)

        assert "line0" in result
        assert "line9" in result
        assert "more lines" not in result

    def test_is_frozen_dataclass(self) -> None:
        """TaskOutputHandler is immutable."""
        handler = TaskOutputHandler()
        assert hash(handler) is not None


class TestDefaultHandlerFactories:
    """Tests for handler factory functions."""

    def test_default_request_handlers_is_empty(self) -> None:
        """default_request_handlers returns empty dict by default."""
        handlers = default_request_handlers()

        assert handlers == {}

    def test_default_output_handlers_is_empty(self) -> None:
        """default_output_handlers returns empty dict by default."""
        handlers = default_output_handlers()

        assert handlers == {}

    def test_can_add_task_handler_to_registry(self) -> None:
        """Handlers can be added to registry for opt-in use."""
        handlers = default_request_handlers()
        handlers["Task"] = TaskRequestHandler()

        assert "Task" in handlers
        assert isinstance(handlers["Task"], TaskRequestHandler)

    def test_can_add_output_handler_with_settings(self) -> None:
        """Output handlers can be configured when added."""
        handlers = default_output_handlers()
        handlers["Task"] = TaskOutputHandler(max_lines=5, verbose=True)

        task_handler = handlers["Task"]
        assert task_handler.max_lines == 5
        assert task_handler.verbose is True
