"""Helper script for tdd_actor_list_validation.robot smoke tests.

Each subcommand exercises the real ``ActorRegistry._actor_name()`` code path
with a provider whose default model contains ``/`` characters to reproduce
bug #592.

After the virtual built-in refactor (issue #10923), built-in actors are
resolved in-memory from the provider registry (never persisted).  Name
sanitisation is exercised through ``list_actors()`` / the virtual-actor path.

The helper reports the **real** outcome: it exits 0 and prints the sentinel
when the operation succeeds (bug is fixed), and exits 1 when the bug is still
present.
"""

from __future__ import annotations

import sys
from collections.abc import Callable
from pathlib import Path
from typing import Any
from unittest.mock import patch

# Ensure local source tree is importable
_SRC = str(Path(__file__).resolve().parents[1] / "src")
if _SRC not in sys.path:
    sys.path.insert(0, _SRC)

# Ensure the features directory is importable for shared mocks
_FEATURES = str(Path(__file__).resolve().parents[1] / "features")
if _FEATURES not in sys.path:
    sys.path.insert(0, _FEATURES)

from mocks.fake_provider import FakeProviderInfo, make_registry  # noqa: E402
from typer.testing import CliRunner  # noqa: E402

from cleveragents.cli.commands.actor import app as actor_app  # noqa: E402

runner = CliRunner()

_PATCH_GET_SERVICES = "cleveragents.cli.commands.actor._get_services"

_MULTI_SLASH_PROVIDERS = [
    FakeProviderInfo(
        name="Openrouter",
        default_model="anthropic/claude-sonnet-4-20250514",
    ),
]


# ---------------------------------------------------------------------------
# Subcommands
# ---------------------------------------------------------------------------


def list_validation_error() -> None:
    """Invoke ``actor list`` with a multi-slash model provider.

    After the virtual built-in refactor, built-in actors are resolved
    in-memory without DB writes.  We verify the command succeeds and
    virtual actor names have exactly one slash (sanitised by _actor_name).
    """
    mock_service, registry = make_registry(_MULTI_SLASH_PROVIDERS)
    with patch(
        _PATCH_GET_SERVICES,
        return_value=(mock_service, registry),
    ):
        result = runner.invoke(actor_app, ["list"])
    if result.exit_code != 0:
        print(
            f"actor list failed with exit code {result.exit_code}",
            file=sys.stderr,
        )
        sys.exit(1)
    # Command succeeded — check virtual actor names have exactly one slash.
    actors = registry.list_actors()
    for actor in actors:
        name: Any = actor.name
        if name.count("/") != 1:
            print(
                f"actor list produced bad name {name!r} with {name.count('/')} slashes",
                file=sys.stderr,
            )
            sys.exit(1)
    print("tdd-actor-list-validation-error-ok")


def name_slash_check() -> None:
    """Verify that virtual built-in actor names have exactly one ``/``.

    After the virtual built-in refactor, names come from
    ``_resolve_virtual_builtin_actors()`` and are never upserted to DB.
    """
    _, registry = make_registry(_MULTI_SLASH_PROVIDERS)
    actors = registry.list_actors()
    assert len(actors) > 0, (
        "list_actors() returned no actors — expected virtual built-ins"
    )
    for actor in actors:
        name: Any = actor.name
        if name.count("/") != 1:
            print(
                f"actor name {name!r} has {name.count('/')} slashes",
                file=sys.stderr,
            )
            sys.exit(1)
    print("tdd-actor-name-slash-check-ok")


def list_json_validation() -> None:
    """Invoke ``actor list --format json`` with a multi-slash model provider.

    After the virtual built-in refactor, virtual actors are resolved
    in-memory and returned by list_actors() without DB writes.
    """
    mock_service, registry = make_registry(_MULTI_SLASH_PROVIDERS)
    with patch(
        _PATCH_GET_SERVICES,
        return_value=(mock_service, registry),
    ):
        result = runner.invoke(actor_app, ["list", "--format", "json"])
    if result.exit_code != 0:
        print(
            f"actor list --format json failed with exit code {result.exit_code}",
            file=sys.stderr,
        )
        sys.exit(1)
    # Command succeeded — check virtual actor names have exactly one slash.
    actors = registry.list_actors()
    for actor in actors:
        name: Any = actor.name
        if name.count("/") != 1:
            print(
                f"actor list --format json produced bad name {name!r} with "
                f"{name.count('/')} slashes",
                file=sys.stderr,
            )
            sys.exit(1)
    print("tdd-actor-list-json-validation-ok")


# ---------------------------------------------------------------------------
# Dispatcher
# ---------------------------------------------------------------------------

_COMMANDS: dict[str, Callable[[], None]] = {
    "list-validation-error": list_validation_error,
    "name-slash-check": name_slash_check,
    "list-json-validation": list_json_validation,
}

if __name__ == "__main__":
    if len(sys.argv) < 2 or sys.argv[1] not in _COMMANDS:
        print(f"Usage: {sys.argv[0]} <{'|'.join(_COMMANDS)}>", file=sys.stderr)
        sys.exit(1)
    cmd = _COMMANDS[sys.argv[1]]
    cmd()
