"""Dependency-free client/CLI for Hermes' local ``node_action`` tool."""

from __future__ import annotations

import http.client
import ipaddress
import json
import os
import sys
from typing import Any, Mapping
from urllib.parse import urlparse

from .hermes_bridge import BRIDGE_PATH


TOKEN_ENV = "OMNI_HERMES_BRIDGE_TOKEN"
ENDPOINT_ENV = "OMNI_HERMES_BRIDGE_URL"


def request_node_action(
    payload: Mapping[str, Any],
    *,
    endpoint: str | None = None,
    token: str | None = None,
    timeout: float = 10.0,
) -> tuple[int, dict[str, Any]]:
    """Invoke an already delegated run ticket; never creates permissions."""

    raw_endpoint = endpoint or os.environ.get(
        ENDPOINT_ENV,
        f"http://127.0.0.1:8766{BRIDGE_PATH}",
    )
    credential = token or os.environ.get(TOKEN_ENV, "")
    if len(credential.encode("utf-8")) < 32:
        raise ValueError(f"{TOKEN_ENV} must contain at least 32 bytes")
    parsed = urlparse(raw_endpoint)
    try:
        address = ipaddress.ip_address(parsed.hostname or "")
    except ValueError as exc:
        raise ValueError("Hermes bridge endpoint must use a literal loopback address") from exc
    if parsed.scheme != "http" or not address.is_loopback or parsed.path != BRIDGE_PATH:
        raise ValueError("Hermes bridge endpoint must be its exact loopback HTTP path")
    encoded = json.dumps(
        dict(payload),
        ensure_ascii=False,
        separators=(",", ":"),
        allow_nan=False,
    ).encode("utf-8")
    if len(encoded) > 64 * 1024:
        raise ValueError("Hermes bridge request exceeds 64 KiB")
    connection = http.client.HTTPConnection(
        parsed.hostname,
        parsed.port or 80,
        timeout=max(0.1, min(float(timeout), 60.0)),
    )
    try:
        connection.request(
            "POST",
            BRIDGE_PATH,
            body=encoded,
            headers={
                "Authorization": f"Bearer {credential}",
                "Content-Type": "application/json",
                "Content-Length": str(len(encoded)),
                "Accept": "application/json",
            },
        )
        response = connection.getresponse()
        raw = response.read(4 * 1024 * 1024 + 1)
        if len(raw) > 4 * 1024 * 1024:
            raise RuntimeError("Hermes bridge response exceeds 4 MiB")
        value = json.loads(raw or b"{}")
        if not isinstance(value, dict):
            raise RuntimeError("Hermes bridge response is not an object")
        return response.status, value
    finally:
        connection.close()


def main() -> int:
    raw = sys.stdin.buffer.read(64 * 1024 + 1)
    if len(raw) > 64 * 1024:
        print('{"error":"request_too_large"}')
        return 2
    try:
        payload = json.loads(raw)
        if not isinstance(payload, dict):
            raise ValueError("JSON root must be an object")
        status, result = request_node_action(payload)
    except Exception as exc:
        print(json.dumps({"error": type(exc).__name__}, separators=(",", ":")))
        return 2
    print(json.dumps(result, ensure_ascii=False, separators=(",", ":")))
    return 0 if 200 <= status < 300 else 1


if __name__ == "__main__":
    raise SystemExit(main())
