from __future__ import annotations

import httpx

from rungate._response import RungateResponse
from tests.conftest import make_openai_response, make_rungate_headers


class TestRungateResponse:
    def test_parses_all_headers(self):
        resp = httpx.Response(
            200,
            json=make_openai_response(),
            headers=make_rungate_headers(
                run_id="run-abc",
                step_id="step-def",
                provider="anthropic",
                model="claude-3",
                tokens_used="150",
                cost_usd="0.005000",
                budget_remaining_usd="9.995000",
                budget_remaining_tokens="9850",
                failover="2",
                warning="audit-log-failure",
                governance="blocked",
            ),
        )
        rr = RungateResponse(resp)

        assert rr.metadata.run_id == "run-abc"
        assert rr.metadata.step_id == "step-def"
        assert rr.metadata.provider == "anthropic"
        assert rr.metadata.model == "claude-3"
        assert rr.metadata.tokens_used == 150
        assert rr.metadata.cost_usd == 0.005
        assert rr.metadata.budget_remaining_usd == 9.995
        assert rr.metadata.budget_remaining_tokens == 9850
        assert rr.metadata.failover_count == 2
        assert rr.metadata.warning == "audit-log-failure"
        assert rr.metadata.governance == "blocked"

    def test_handles_missing_headers(self):
        resp = httpx.Response(200, json=make_openai_response(), headers={})
        rr = RungateResponse(resp)

        assert rr.metadata.run_id is None
        assert rr.metadata.cost_usd is None
        assert rr.metadata.budget_remaining_usd is None
        assert rr.metadata.failover_count is None
        assert rr.metadata.warning is None

    def test_parses_cost_as_float(self):
        resp = httpx.Response(
            200,
            json=make_openai_response(),
            headers={"x-rungate-cost-usd": "0.123456"},
        )
        rr = RungateResponse(resp)
        assert rr.metadata.cost_usd == 0.123456

    def test_parses_tokens_as_int(self):
        resp = httpx.Response(
            200,
            json=make_openai_response(),
            headers={"x-rungate-tokens-used": "1500"},
        )
        rr = RungateResponse(resp)
        assert rr.metadata.tokens_used == 1500

    def test_body_returns_parsed_json(self):
        body = make_openai_response(content="Test response")
        resp = httpx.Response(200, json=body)
        rr = RungateResponse(resp)

        assert rr.body["id"] == "chatcmpl-test-123"
        assert rr.body["choices"][0]["message"]["content"] == "Test response"

    def test_status_code(self):
        resp = httpx.Response(200, json=make_openai_response())
        rr = RungateResponse(resp)
        assert rr.status_code == 200

    def test_non_json_body_returns_raw_text(self):
        resp = httpx.Response(200, text="<html>Server Error</html>")
        rr = RungateResponse(resp)
        assert "_raw" in rr.body
        assert "Server Error" in rr.body["_raw"]

    def test_empty_body_returns_raw(self):
        resp = httpx.Response(200, text="")
        rr = RungateResponse(resp)
        assert "_raw" in rr.body

    def test_malformed_header_values_parse_as_none(self):
        resp = httpx.Response(
            200,
            json=make_openai_response(),
            headers={"x-rungate-tokens-used": "abc", "x-rungate-cost-usd": "not-a-number"},
        )
        rr = RungateResponse(resp)
        assert rr.metadata.tokens_used is None
        assert rr.metadata.cost_usd is None
