"""HTTP transport implementation using urllib.request."""

from __future__ import annotations

import json
import time
from typing import TYPE_CHECKING, Callable
from urllib import request as urlrequest

from vedatrace.models import LogRecord

if TYPE_CHECKING:
    from vedatrace.config import RetryConfig


class HttpTransport:
    """Transport that sends log batches to the VedaTrace ingest endpoint."""

    def __init__(
        self,
        api_key: str,
        endpoint: str = "https://ingest.vedatrace.dev/v1/logs",
        timeout_seconds: float = 5.0,
        *,
        retry: RetryConfig | None = None,
        on_error: Callable[[Exception], None] | None = None,
        sleep_fn: Callable[[float], None] = time.sleep,
    ) -> None:
        self._api_key = api_key
        self._endpoint = endpoint
        self._timeout_seconds = timeout_seconds
        self._retry = retry
        self._on_error = on_error
        self._sleep_fn = sleep_fn

    def emit(self, records: list[LogRecord]) -> None:
        """Send records as a JSON array using HTTP POST."""

        payload = [record.to_wire() for record in records]
        body = json.dumps(payload).encode("utf-8")
        retry_count = 0 if self._retry is None else self._retry.max_retries
        retry_delay = 0.0 if self._retry is None else self._retry.retry_delay_seconds
        last_error: Exception | None = None

        for attempt in range(1, retry_count + 2):
            try:
                self._send(body)
                return None
            except Exception as exc:
                last_error = exc
                if attempt > retry_count:
                    break
                try:
                    self._sleep_fn(retry_delay)
                except Exception as sleep_exc:
                    last_error = sleep_exc
                    break

        if last_error is not None:
            self._safe_on_error(last_error)
        return None

    def close(self) -> None:
        """No-op close for interface compatibility."""

        return None

    def _send(self, payload_bytes: bytes) -> None:
        """Send a single HTTP request attempt."""

        req = urlrequest.Request(
            self._endpoint,
            data=payload_bytes,
            headers={
                "Content-Type": "application/json",
                "X-API-Key": self._api_key,
            },
            method="POST",
        )
        with urlrequest.urlopen(req, timeout=self._timeout_seconds) as response:
            status = getattr(response, "status", None)
            if status is None and hasattr(response, "getcode"):
                status = response.getcode()
            if status is not None and not 200 <= int(status) < 300:
                raise RuntimeError(f"HTTP transport request failed with status {status}")

    def _safe_on_error(self, exc: Exception) -> None:
        """Invoke on_error without allowing callback failures to escape."""

        if self._on_error is None:
            return None
        try:
            self._on_error(exc)
        except Exception:
            return None
        return None
