from typing import cast

import pytest

import click
import typer

from yee88 import cli, engines, plugins
from tests.plugin_fixtures import FakeEntryPoint, install_entrypoints


@pytest.fixture
def engine_entrypoints(monkeypatch):
    entrypoints = [
        FakeEntryPoint(
            "codex",
            "yee88.runners.codex:BACKEND",
            plugins.ENGINE_GROUP,
        ),
        FakeEntryPoint(
            "claude",
            "yee88.runners.claude:BACKEND",
            plugins.ENGINE_GROUP,
        ),
        FakeEntryPoint(
            "bad-id",
            "yee88.runners.bad:BACKEND",
            plugins.ENGINE_GROUP,
        ),
    ]
    install_entrypoints(monkeypatch, entrypoints)
    monkeypatch.setattr(cli, "_load_settings_optional", lambda: (None, None))
    return entrypoints


def test_engine_discovery_filters_invalid_ids(engine_entrypoints) -> None:
    ids = engines.list_backend_ids()
    assert ids == ["claude", "codex"]


def test_cli_registers_engine_commands_sorted(engine_entrypoints) -> None:
    app = cli.create_app()
    command_names = [cmd.name for cmd in app.registered_commands]
    engine_ids = engines.list_backend_ids()
    assert set(engine_ids) <= set(command_names)
    engine_commands = [name for name in command_names if name in engine_ids]
    assert engine_commands == engine_ids


def test_engine_commands_do_not_expose_engine_id_option(
    engine_entrypoints,
) -> None:
    app = cli.create_app()
    group = cast(click.Group, typer.main.get_command(app))
    engine_ids = engines.list_backend_ids()

    ctx = group.make_context("yee88", [])

    for engine_id in engine_ids:
        command = group.get_command(ctx, engine_id)
        assert command is not None
        options: set[str] = set()
        for param in command.params:
            options.update(getattr(param, "opts", []))
            options.update(getattr(param, "secondary_opts", []))
        assert "--final-notify" in options
        assert "--debug" in options
        assert not any(opt.lstrip("-") == "engine-id" for opt in options)
