"""andrea_svc_auth.client — the SERVICE side: post an authenticated afferent
gem event. Stdlib-only (urllib), so the leanest consumer (pool_worker baked into
every worker image) carries no extra deps. The API key is sent in the same header
the server validates (default X-Agent-Key), read from ANDREA_SVC_API_KEY unless
passed explicitly. Best-effort by contract: the caller decides whether to swallow
errors (event reporting must never take down the reporter)."""
from __future__ import annotations

import json
import os
import urllib.request
from typing import Optional

from .core import DEFAULT_API_KEY_HEADER

API_KEY_ENV = "ANDREA_SVC_API_KEY"


def post_event(
    url: str,
    *,
    source: str,
    body: str,
    severity: str = "info",
    api_key: Optional[str] = None,
    api_key_header: str = DEFAULT_API_KEY_HEADER,
    timeout: float = 8.0,
    extra: Optional[dict] = None,
):
    """POST {source, severity, body, **extra} to a gem /event endpoint with the
    service API key attached. Returns the HTTP status. Raises on transport/HTTP
    error — wrap at the call site if the emission must be silent.

    api_key precedence: explicit arg > ANDREA_SVC_API_KEY env. If neither is set,
    NO key header is sent (the request will be denied by an auth-required endpoint
    — fail-closed by omission, surfaced as a 401/403 the caller can log)."""
    payload = {"source": source, "severity": severity, "body": body}
    if extra:
        payload.update(extra)
    headers = {"Content-Type": "application/json"}
    key = api_key if api_key is not None else os.getenv(API_KEY_ENV, "")
    if key:
        headers[api_key_header] = key
    req = urllib.request.Request(
        url, data=json.dumps(payload).encode("utf-8"), method="POST", headers=headers)
    with urllib.request.urlopen(req, timeout=timeout) as resp:
        status = getattr(resp, "status", None)
        return status if status is not None else resp.getcode()
