"""Tests for HTTP transport request construction."""

from __future__ import annotations

import json
import pathlib
import sys
import unittest
from unittest import mock


ROOT = pathlib.Path(__file__).resolve().parents[1]
SRC = ROOT / "src"
if str(SRC) not in sys.path:
    sys.path.insert(0, str(SRC))

from vedatrace.models import LogLevel, LogRecord
from vedatrace.transports.http import HttpTransport


class _FakeResponse:
    def __init__(self, status: int = 200) -> None:
        self.status = status

    def __enter__(self) -> "_FakeResponse":
        return self

    def __exit__(self, exc_type, exc, tb) -> None:
        return None

    def getcode(self) -> int:
        return self.status


class TestHttpTransport(unittest.TestCase):
    def test_emit_builds_post_request_with_expected_headers_and_body(self) -> None:
        captured: dict[str, object] = {}
        api_key = "vt_live_test_key_123"
        transport = HttpTransport(api_key=api_key)
        record = LogRecord.create(
            level=LogLevel.WARNING,
            message="disk almost full",
            service="billing",
            timestamp="2026-02-19T17:42:47.957694Z",
            metadata={"disk_pct": 92},
        )

        def fake_urlopen(req, timeout):  # type: ignore[no-untyped-def]
            captured["request"] = req
            captured["timeout"] = timeout
            return _FakeResponse(status=200)

        with mock.patch("vedatrace.transports.http.urlrequest.urlopen", new=fake_urlopen):
            transport.emit([record])

        req = captured["request"]
        self.assertEqual(req.full_url, "https://ingest.vedatrace.dev/v1/logs")
        self.assertEqual(req.get_method(), "POST")

        headers = {k.lower(): v for k, v in req.header_items()}
        self.assertEqual(headers.get("content-type"), "application/json")
        self.assertIn("x-api-key", headers)
        self.assertEqual(headers.get("x-api-key"), api_key)

        body_bytes = req.data
        self.assertIsInstance(body_bytes, bytes)
        payload = json.loads(body_bytes.decode("utf-8"))
        self.assertIsInstance(payload, list)
        self.assertEqual(len(payload), 1)

        item = payload[0]
        self.assertEqual(
            set(item.keys()),
            {"level", "message", "service", "timestamp", "metadata"},
        )
        self.assertEqual(item["level"], "warning")
        self.assertIsInstance(item["level"], str)

    def test_non_2xx_status_is_reported_to_on_error_without_raising(self) -> None:
        seen: list[Exception] = []
        transport = HttpTransport(
            api_key="vt_live_test_key_456",
            on_error=seen.append,
        )
        record = LogRecord.create(
            level=LogLevel.ERROR,
            message="failed op",
            service="orders",
            timestamp="2026-02-19T17:42:47.957694Z",
            metadata={},
        )

        with mock.patch(
            "vedatrace.transports.http.urlrequest.urlopen",
            return_value=_FakeResponse(status=503),
        ):
            transport.emit([record])

        self.assertEqual(len(seen), 1)
        self.assertIsInstance(seen[0], RuntimeError)
        self.assertIn("503", str(seen[0]))
