"""Tests for the Nous-credits subscription % gauge in build_nous_credits_snapshot.

Covers the monthly_credits denominator path added when the portal /api/oauth/account
subscription block began carrying `monthly_credits`. Magnitudes-only fallback, clamp,
and the non-finite / rollover guards (surfaced by adversarial review) are all asserted.
"""
from hermes_cli.nous_account import (
    NousPortalAccountInfo,
    NousPaidServiceAccessInfo,
    NousPortalSubscriptionInfo,
    _subscription_from_payload,
)
from agent.account_usage import build_nous_credits_snapshot, render_account_usage_lines


def _acct(**kwargs):
    kwargs.setdefault("logged_in", True)
    kwargs.setdefault("source", "account_api")
    kwargs.setdefault("fresh", True)
    kwargs.setdefault("portal_base_url", "https://portal.nousresearch.com")
    return NousPortalAccountInfo(**kwargs)


def _window(snap):
    return snap.windows[0] if (snap and snap.windows) else None


def test_parser_captures_monthly_credits():
    sub = _subscription_from_payload({
        "plan": "Ultra", "tier": 14, "monthly_charge": 200, "monthly_credits": 220,
        "current_period_end": "2026-06-28T05:21:54.000Z",
        "credits_remaining": 219.27341839, "rollover_credits": 0,
    })
    assert sub.monthly_credits == 220
    assert abs(sub.credits_remaining - 219.27341839) < 1e-6




def test_gauge_present_with_monthly_credits():
    snap = build_nous_credits_snapshot(_acct(
        paid_service_access=True,
        subscription=NousPortalSubscriptionInfo(
            plan="Ultra", monthly_credits=220, credits_remaining=219.27341839,
            current_period_end="2026-06-28"),
        paid_service_access_info=NousPaidServiceAccessInfo(
            subscription_credits_remaining=219.27, total_usable_credits=219.27),
    ))
    w = _window(snap)
    assert w is not None and w.label == "Subscription"
    assert abs(w.used_percent - (220 - 219.27341839) / 220 * 100) < 1e-9
    blob = "\n".join(render_account_usage_lines(snap))
    assert "% used" in blob or "% remaining" in blob
    assert "of $220.00 left" in blob










def test_nan_remaining_no_window_no_nan_string():
    """json.loads parses bare NaN by default; isinstance(nan, float) is True.
    The gauge must reject it rather than render '$nan' + a false 100% used."""
    snap = build_nous_credits_snapshot(_acct(
        paid_service_access=True,
        subscription=NousPortalSubscriptionInfo(monthly_credits=220, credits_remaining=float("nan")),
        paid_service_access_info=NousPaidServiceAccessInfo(purchased_credits_remaining=5.0),
    ))
    assert _window(snap) is None
    assert "$nan" not in "\n".join(render_account_usage_lines(snap)).lower()










def test_failopen_none_and_logged_out():
    assert build_nous_credits_snapshot(None) is None
    assert build_nous_credits_snapshot(_acct(logged_in=False)) is None
