"""Unit tests for the command registry ``match`` helper."""

from __future__ import annotations

from clients.terminal.tui.commands.base import BaseCommand, CommandMeta
from clients.terminal.tui.commands.registry import CommandRegistry


class _Cmd(BaseCommand):
    def __init__(self, meta: CommandMeta) -> None:
        self.meta = meta

    async def execute(self, ctx, args: str) -> None:  # pragma: no cover - unused here
        raise NotImplementedError


def _registry() -> CommandRegistry:
    reg = CommandRegistry()
    reg.register(_Cmd(CommandMeta("new", ("clear",), "Start new session")))
    reg.register(_Cmd(CommandMeta("sessions", ("resume", "continue"), "List sessions")))
    reg.register(_Cmd(CommandMeta("switch", (), "Switch session")))
    return reg


def test_match_empty_prefix_returns_all() -> None:
    reg = _registry()
    assert {c.meta.name for c in reg.match("")} == {"new", "sessions", "switch"}


def test_match_prefix_matches_name_and_alias() -> None:
    reg = _registry()
    names = {c.meta.name for c in reg.match("s")}
    assert names == {"sessions", "switch"}


def test_match_exact_name_sorts_first() -> None:
    reg = _registry()
    matched = reg.match("switch")
    assert [c.meta.name for c in matched] == ["switch"]


def test_match_exact_alias_sorts_first() -> None:
    reg = _registry()
    # "s" prefix-matches sessions + switch; "sessions" is an exact name but also
    # "resume"/"continue" are aliases of sessions. Exact name match should win.
    matched = reg.match("se")
    assert matched[0].meta.name == "sessions"


def test_match_resolves_alias_exact() -> None:
    reg = _registry()
    matched = reg.match("resume")
    assert [c.meta.name for c in matched] == ["sessions"]


def test_match_no_matches_returns_empty() -> None:
    reg = _registry()
    assert reg.match("zzz") == []


def test_match_is_case_insensitive() -> None:
    reg = _registry()
    assert {c.meta.name for c in reg.match("SW")} == {"switch"}


def test_match_strips_whitespace() -> None:
    reg = _registry()
    assert {c.meta.name for c in reg.match("  new  ")} == {"new"}