from __future__ import annotations

import pytest

from jarvis_gateway.adapters.finance_live_readonly import FinanceLiveReadonlyAdapter


class FakeHttp:
    def __init__(self, responses: dict[str, object] | None = None, fail: bool = False) -> None:
        self.responses = responses or {}
        self.fail = fail
        self.calls: list[tuple[str, str, float]] = []

    def get_json(self, url: str, timeout: float) -> object:
        self.calls.append(("GET", url, timeout))
        if self.fail:
            raise TimeoutError("connect failed /home/agent/finance.sqlite3 token=abc")
        return self.responses.get(url.rsplit("/api", 1)[-1] if "/api" in url else url, {"ok": True})


def test_live_adapter_uses_only_allowed_get_endpoints() -> None:
    fake = FakeHttp({
        "/health": {"status": "ok"},
        "/provider/status": {"connected": True, "balance": 12345},
        "/runtime/status": {"reachable": True},
        "/system/status": {"ok": True},
        "/budget/import-status-audit": {"status": "warning", "review_items": 2},
    })
    adapter = FinanceLiveReadonlyAdapter(base_url="http://127.0.0.1:9000", http_client=fake, timeout_seconds=2)

    snapshot = adapter.get_snapshot()

    assert {method for method, _, _ in fake.calls} == {"GET"}
    assert [url.rsplit("/api", 1)[-1] for _, url, _ in fake.calls] == [
        "/health",
        "/provider/status",
        "/runtime/status",
        "/system/status",
        "/budget/import-status-audit",
    ]
    assert snapshot.module_id == "finance"
    assert snapshot.source_health.source_type == "http_api"
    assert snapshot.display_policy == "summary"
    assert "12345" not in str(snapshot.model_dump(mode="json"))


def test_live_adapter_offline_returns_safe_offline_snapshot() -> None:
    adapter = FinanceLiveReadonlyAdapter(base_url="http://127.0.0.1:9000", http_client=FakeHttp(fail=True), timeout_seconds=1)
    snapshot = adapter.get_snapshot()
    dumped = snapshot.model_dump(mode="json")
    assert dumped["status"] in {"offline", "degraded"}
    assert dumped["source_health"]["reachable"] is False
    assert "FinanceManager nicht erreichbar" in str(dumped)
    assert "/home/agent" not in str(dumped)
    assert "token" not in str(dumped).lower()


def test_live_adapter_rejects_missing_base_url() -> None:
    with pytest.raises(ValueError):
        FinanceLiveReadonlyAdapter(base_url="")
