"""Cliente HTTP del xamiSDK hacia Xami (api.xami.run).

Encapsula las llamadas a los endpoints de pareo/activacion. Usa solo la libreria
estandar (urllib) para no exigir dependencias pesadas.
"""
from __future__ import annotations
import hashlib
import json
import platform
import socket
import urllib.request
import urllib.error

DEFAULT_ENDPOINT = "https://api.xami.run"


class XamiClient:
    def __init__(self, endpoint: str = DEFAULT_ENDPOINT, timeout: int = 20):
        self.endpoint = endpoint.rstrip("/")
        self.timeout = timeout

    def _post(self, path: str, payload: dict) -> dict:
        url = self.endpoint + path
        data = json.dumps(payload).encode()
        req = urllib.request.Request(url, data=data,
                                     headers={"Content-Type": "application/json"})
        try:
            with urllib.request.urlopen(req, timeout=self.timeout) as r:
                return json.loads(r.read().decode())
        except urllib.error.HTTPError as e:
            body = e.read().decode(errors="replace")
            try:
                detail = json.loads(body).get("detail", body)
            except Exception:
                detail = body
            raise XamiError(f"HTTP {e.code}: {detail}") from None
        except urllib.error.URLError as e:
            raise XamiError(f"no se pudo conectar a {url}: {e.reason}") from None

    def pair(self, sdk_key: str, secret: str, sdk_pubkey_pem: str,
             receive_url: str | None, sdk_version: str, host_fingerprint: str) -> dict:
        return self._post("/v1/sdk/pair", {
            "sdk_key": sdk_key, "secret": secret, "sdk_pubkey": sdk_pubkey_pem,
            "receive_url": receive_url, "sdk_version": sdk_version,
            "host_fingerprint": host_fingerprint,
        })

    def activate(self, sdk_key: str, secret: str) -> dict:
        return self._post("/v1/sdk/activate", {"sdk_key": sdk_key, "secret": secret})


class XamiError(Exception):
    pass


def host_fingerprint() -> str:
    """Huella estable del host (para detectar uso en multiples maquinas). No es
    seguridad fuerte, solo telemetria/deteccion."""
    parts = [platform.node(), platform.machine(), platform.system()]
    try:
        parts.append(socket.gethostname())
    except Exception:
        pass
    raw = "|".join(p for p in parts if p)
    return hashlib.sha256(raw.encode()).hexdigest()[:32]
