"""User-facing wording contracts for ``hermes update`` failure/partial output.

Invariants only (what the user must be able to read and act on), never whole-string snapshots.
"""

from __future__ import annotations

import subprocess

import pytest

from hermes_cli import update_cmd
import hermes_cli.update_receipt as ur

class TestFleetMatrixVerdict:
    """cli-09: a stale/down fleet must end with an explicit "not complete" verdict, because
    ``✓ Update complete!`` was already printed before the restart phase."""

    def test_stale_rows_print_counted_verdict_with_commands(self, capsys):
        fleet = [
            {"profile": "default", "pid": 1234, "code_sha": "abc12345ff", "state": "stale"},
            {"profile": "work", "pid": 99, "code_sha": None, "state": "down"},
            {"profile": "ok", "pid": 7, "code_sha": "a" * 40, "state": "current"},
        ]
        assert ur.print_fleet_version_matrix(fleet) is True
        out = capsys.readouterr().out
        assert "hermes gateway restart" in out

    def test_unknown_rows_print_no_verdict(self, capsys):
        fleet = [{"profile": "default", "pid": 1, "code_sha": None, "state": "unknown"}]
        assert ur.print_fleet_version_matrix(fleet) is False

class TestCalledProcessErrorMessage:
    """cli-10: a dependency-install failure leads with a plain sentence, not the exception repr."""

    @pytest.fixture
    def no_exit(self, monkeypatch):
        monkeypatch.setattr(update_cmd, "_finalize_receipt", lambda *_a, **_k: None)
        monkeypatch.setattr(update_cmd.sys, "exit", lambda code=0: (_ for _ in ()).throw(SystemExit(code)))

    def test_dep_install_failure_lead_and_next_step(self, capsys, no_exit, monkeypatch):
        monkeypatch.setattr(update_cmd._m(), "_is_windows", lambda: False)
        exc = subprocess.CalledProcessError(1, ["uv", "pip", "install", "-e", ".[all]"], stderr="error: disk full")
        with pytest.raises(SystemExit) as info:
            update_cmd._handle_update_called_process_error(exc, object(), False, False)
        assert info.value.code == 1
        out = capsys.readouterr().out
        assert "disk full" in out
