"""POST /api/model/set must never copy an env-expanded secret into config.yaml.

Regression for #88990: ``_apply_model_assignment_sync`` ran on the
env-EXPANDED config, so a provider entry whose raw yaml held
``api_key: ${MY_KEY}`` (or a ``key_env`` pointer) got its RESOLVED plaintext
key copied under ``model.api_key`` and persisted. ``_preserve_env_ref_templates``
cannot rescue it — no template ever lived at ``model.api_key``.

The fix prefers the credential pointer: ``key_env`` when the raw entry has
one, else the raw ``${VAR}`` template, and only falls back to the expanded
value when the key is stored as a literal on disk (no new exposure).
"""

import importlib
import sys

import pytest


SECRET = "sk-SUPERSECRET-e2e-12345"


@pytest.fixture()
def isolated_home(tmp_path, monkeypatch):
    home = tmp_path / ".hermes"
    home.mkdir()
    monkeypatch.setenv("HERMES_HOME", str(home))
    monkeypatch.setenv("MY_SECRET_KEY", SECRET)
    # Config caches are keyed per-path, but reload the config module state so
    # nothing from a previous test's HERMES_HOME bleeds in.
    for mod in ("hermes_cli.config",):
        if mod in sys.modules:
            importlib.reload(sys.modules[mod])
    return home


def _write_config(home, body: str) -> None:
    (home / "config.yaml").write_text(body, encoding="utf-8")


def _apply(provider="myprov", model="test-model"):
    from hermes_cli.web_server_config import _apply_model_assignment_sync

    return _apply_model_assignment_sync("main", provider, model, "", "")


def _model_block(home) -> str:
    text = (home / "config.yaml").read_text(encoding="utf-8")
    return text.split("providers:")[0]


class TestModelSetSecretHandling:
    def test_env_template_key_is_copied_as_template_not_plaintext(self, isolated_home):
        _write_config(
            isolated_home,
            "model:\n  provider: openrouter\n  default: some/model\n"
            "providers:\n  myprov:\n    base_url: https://api.example.com/v1\n"
            "    api_key: ${MY_SECRET_KEY}\n    model: test-model\n",
        )

        _apply()

        text = (isolated_home / "config.yaml").read_text(encoding="utf-8")
        assert SECRET not in text
        assert "api_key: ${MY_SECRET_KEY}" in _model_block(isolated_home)

    def test_key_env_pointer_is_preferred_over_api_key(self, isolated_home, monkeypatch):
        monkeypatch.setenv("MYPROV_KEY", SECRET)
        _write_config(
            isolated_home,
            "model:\n  provider: openrouter\n  default: some/model\n"
            "providers:\n  myprov:\n    base_url: https://api.example.com/v1\n"
            "    key_env: MYPROV_KEY\n    api_key: ${MYPROV_KEY}\n    model: test-model\n",
        )

        _apply()

        text = (isolated_home / "config.yaml").read_text(encoding="utf-8")
        block = _model_block(isolated_home)
        assert SECRET not in text
        assert "key_env: MYPROV_KEY" in block
        assert "api_key" not in block

    def test_literal_on_disk_key_keeps_legacy_copy_behavior(self, isolated_home):
        _write_config(
            isolated_home,
            "model:\n  provider: openrouter\n  default: some/model\n"
            "providers:\n  myprov:\n    base_url: https://api.example.com/v1\n"
            "    api_key: sk-literal-on-disk\n    model: test-model\n",
        )

        _apply()

        assert "api_key: sk-literal-on-disk" in _model_block(isolated_home)
