"""profiles.configure honours the model selection guard (#95293 remainder).

The Bots-mode editor writes a profile's default model through
``profiles.configure`` — a surface that historically bypassed the
data-policy / expensive-model selection guard every other model-switch path
enforces (``config.set model`` answers ``confirm_required`` and waits for a
``confirm_expensive_model`` resend).  A guarded pick made from the Bots
surface was therefore applied silently, with no confirm flow anywhere.

These tests pin the same handshake contract on ``profiles.configure``:

* a guarded model WITHOUT ``confirm_expensive_model`` answers
  ``confirm_required`` + ``confirm_message`` and writes NOTHING;
* the confirmed resend (``confirm_expensive_model: true``) writes;
* unguarded models keep writing exactly as before.
"""

from __future__ import annotations

from pathlib import Path
from types import SimpleNamespace

import pytest
import hermes_yaml as yaml

import hermes_cli.model_selection_guards as guards
import tui_gateway.server as srv

GUARDED_MODEL = "muse-spark-1.2-contributor"
GUARD_MESSAGE = "CONTRIBUTOR TIER: this model may train on your data."


@pytest.fixture
def home(tmp_path, monkeypatch):
    hermes_home = tmp_path / ".hermes"
    hermes_home.mkdir()
    monkeypatch.setenv("HERMES_HOME", str(hermes_home))
    # The profile write now validates through ``switch_model`` (catalog + credentials); these
    # tests pin the guard handshake, so echo the pick back as an accepted route.
    from hermes_cli.model_switch import ModelSwitchResult
    monkeypatch.setattr(
        "hermes_cli.model_switch.switch_model",
        lambda *, raw_input, explicit_provider, **_kw: ModelSwitchResult(
            success=True, new_model=raw_input, target_provider=explicit_provider))
    return hermes_home


@pytest.fixture
def contributor_guard(monkeypatch):
    """Fire the selection guard for GUARDED_MODEL only, like the real
    data-policy guard fires for ``-contributor`` ids."""

    def fake_combined_selection_warning(model_name, **_kwargs):
        if model_name == GUARDED_MODEL:
            return SimpleNamespace(message=GUARD_MESSAGE, kind="data_policy")
        return None

    monkeypatch.setattr(guards, "combined_selection_warning", fake_combined_selection_warning)


def _configure(params):
    return srv._methods["profiles.configure"]("configure", {"name": "default", **params})["result"]


def _profile_model(home: Path):
    cfg_path = home / "config.yaml"
    if not cfg_path.is_file():
        return None
    cfg = yaml.safe_load(cfg_path.read_text()) or {}
    model_cfg = cfg.get("model") or {}
    return model_cfg.get("default")


def test_guarded_model_answers_confirm_required_and_writes_nothing(home, contributor_guard):
    result = _configure({"model": GUARDED_MODEL, "provider": "opencode-go"})

    assert result.get("confirm_required") is True
    assert GUARD_MESSAGE in (result.get("confirm_message") or "")
    # The model section is PENDING confirmation, not failed — it must not
    # poison ``ok`` (the Bots editor toasts "Some sections failed" on False).
    assert result["applied"].get("model") is not False
    assert _profile_model(home) != GUARDED_MODEL


def test_confirmed_resend_writes_the_guarded_model(home, contributor_guard):
    result = _configure(
        {
            "model": GUARDED_MODEL,
            "provider": "opencode-go",
            "confirm_expensive_model": True,
        }
    )

    assert not result.get("confirm_required")
    assert result["applied"].get("model") is True
    assert _profile_model(home) == GUARDED_MODEL


def test_unguarded_model_still_writes_without_confirmation(home, contributor_guard):
    result = _configure({"model": "hermes-4.5-405b", "provider": "nous"})

    assert not result.get("confirm_required")
    assert result["applied"].get("model") is True
    assert _profile_model(home) == "hermes-4.5-405b"


def test_other_sections_still_apply_while_model_awaits_confirmation(home, contributor_guard):
    result = _configure(
        {
            "model": GUARDED_MODEL,
            "provider": "opencode-go",
            "soul": "# SOUL\nBe kind.",
        }
    )

    assert result.get("confirm_required") is True
    assert result["applied"].get("soul") is True
    assert _profile_model(home) != GUARDED_MODEL
