from __future__ import annotations

import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

from modules.im.discord import _prioritize_claude_model_choices


def test_prioritize_pulls_aliases_ahead_of_catalog_tail():
    # claude_models() appends the bare aliases after the full catalog.
    models = ["claude-fable-5", "claude-opus-4-8", "opus", "sonnet", "haiku"]
    result = _prioritize_claude_model_choices(models, None)

    assert result[:3] == ["opus", "sonnet", "haiku"]
    # No entries gained or lost — only reordered.
    assert sorted(result) == sorted(models)


def test_prioritize_puts_current_selection_first():
    models = ["claude-fable-5", "claude-opus-4-8", "opus", "sonnet", "haiku"]
    result = _prioritize_claude_model_choices(models, "claude-opus-4-8")

    assert result[0] == "claude-opus-4-8"
    assert result[1:4] == ["opus", "sonnet", "haiku"]
    assert sorted(result) == sorted(models)


def test_prioritize_ignores_missing_or_default_selection():
    models = ["claude-fable-5", "opus"]

    # __default__ / None / unknown ids are not real catalog entries and must not
    # be injected into the option list.
    assert _prioritize_claude_model_choices(models, "__default__") == ["opus", "claude-fable-5"]
    assert _prioritize_claude_model_choices(models, None) == ["opus", "claude-fable-5"]


def test_prioritized_aliases_survive_discord_25_cap():
    # Regression for the P2: 24 catalog ids plus the 3 bare aliases appended last.
    # The Claude modal prepends one default option then slices model_options to 25,
    # so only the first 24 model entries survive. Prioritization must keep the
    # always-valid aliases inside that window.
    catalog = [f"claude-catalog-{i}" for i in range(24)]
    models = catalog + ["opus", "sonnet", "haiku"]

    result = _prioritize_claude_model_choices(models, None)

    assert {"opus", "sonnet", "haiku"} <= set(result[:24])
