"""The app must SAY what it is running, and must not lie when it cannot find out.

There is no frontend test runner in this repo, so these are source-inspection
guards in the unit lane — the same idiom `check_plugin.py` uses on the hook
shells. They are deliberately few and deliberately about ONE property each,
because a grep-shaped test that asserts a whole file's contents fails on every
refactor and gets deleted.

WHY THIS FILE EXISTS. #3298: with a deploy misbehaving, nothing on the instance
could say which commit was serving it, and the one endpoint whose job that is
answered with the name of a branch. The value was fixed then. This is the other
half — the value reaching a person — and #3127 checklist 12 is specific about
the way it goes wrong: *never let a blank stand in for `unknown`*. A readout
that renders a plausible value it never received is worse than one that renders
nothing, because it ends the investigation instead of starting it.
"""
from __future__ import annotations

import re
from pathlib import Path

FRONTEND = Path(__file__).resolve().parents[1] / "frontend" / "src"


def test_something_actually_reads_the_version_endpoint():
    """The endpoint is not enough; something must ask it.

    `/api/version` answered correctly for weeks with no caller — an endpoint
    reachable only by someone who already knew to curl it. Rule 27: a
    capability with no surface the operator can touch is not shipped.
    """
    hits = [p for p in FRONTEND.rglob("*.ts") if "/api/version" in p.read_text()]
    assert hits, "nothing under frontend/src fetches /api/version"


def test_the_footer_does_not_default_to_a_plausible_version():
    """The regression this readout was built to remove.

    `appVersion` used to start life as the literal `"dev"` and the fetch
    swallowed its own failure, so an instance that could not answer rendered
    exactly what a healthy local build renders. Two very different states, one
    string, and no way to tell them apart from the page.

    Pinned as "the ref does not start at a version-shaped literal" rather than
    as an exact initialiser, so a later refactor can change how the state is
    held without failing here — what must not come back is the plausible
    default.
    """
    app = (FRONTEND / "App.vue").read_text()
    match = re.search(r"const appVersion = ref[^;]*;", app)
    assert match, "App.vue no longer declares appVersion — update this guard"
    decl = match.group(0)
    assert '"dev"' not in decl and "'dev'" not in decl, (
        f"appVersion defaults to a version-shaped literal: {decl}\n"
        "A failed fetch would render as a real-looking version (#3127 "
        "checklist 12). Start from a not-answered-yet value instead."
    )


def test_optional_version_fields_are_read_by_absence_not_falsiness():
    """`build` is a number and 0 is a legitimate ordering key.

    The payload omits what it does not know rather than sending `""` or `0`, so
    the renderer's job is to distinguish ABSENT from present. `||` cannot: it
    would report a real `build` of 0 as unknown, and it is the form a person
    reaches for by habit. `??` is the correct one, which is why this pins the
    operator rather than the rendered output.
    """
    view = (FRONTEND / "views" / "SettingsView.vue").read_text()
    for field in ("channel", "build"):
        assert f'versionInfo.{field} ?? "unknown"' in view, (
            f"the {field} readout must use `?? \"unknown\"`, never `|| \"unknown\"` — "
            "an absent field and a falsy one are different answers"
        )


def test_the_version_request_carries_a_deadline():
    """Rule 156. A wait with no deadline cannot report that it failed.

    This readout is consulted when an instance is misbehaving, which is exactly
    when it may never answer. Without a deadline the surface sits on "still
    loading" forever — the blank standing in for `unknown` again, arrived at
    from the other direction.
    """
    src = (FRONTEND / "api" / "version.ts").read_text()
    assert "timeoutMs" in src, "the version fetch must pass a deadline"
