"""
Agent Security Graph telemetry sender for scandar-guard.

Opt-in fleet telemetry — sends anonymized session metadata to the
Agent Security Graph when asg_telemetry=True in GuardConfig.

What is sent: agent_id, session_key, event_type, tool_names (no args),
              finding_categories (no content), threat_score, timestamp.

What is NEVER sent: prompts, responses, tool arguments, user data,
                    file content, or any conversation content.
"""
from __future__ import annotations

import json
import threading
import urllib.request
from datetime import datetime, timezone
from typing import Optional

_DEFAULT_ENDPOINT = "https://scandar.ai/api/v1/asg/events"
_TIMEOUT_S = 3


class AsgTelemetrySender:
    """
    Fire-and-forget telemetry sender. Never blocks, never raises.
    All sends happen on a daemon thread.
    """

    def __init__(
        self,
        api_key: str,
        agent_id: str,
        endpoint: str = _DEFAULT_ENDPOINT,
        parent_agent_id: Optional[str] = None,
    ) -> None:
        self._api_key = api_key
        self._agent_id = agent_id
        self._endpoint = endpoint
        self._parent_agent_id = parent_agent_id

    def _send(self, payload: dict) -> None:
        """Send payload on a background thread. Never raises."""
        def _post() -> None:
            try:
                data = json.dumps(payload).encode("utf-8")
                req = urllib.request.Request(
                    self._endpoint,
                    data=data,
                    headers={
                        "Content-Type": "application/json",
                        "Authorization": f"Bearer {self._api_key}",
                    },
                    method="POST",
                )
                with urllib.request.urlopen(req, timeout=_TIMEOUT_S):
                    pass
            except Exception:
                pass  # Telemetry must never affect the agent

        t = threading.Thread(target=_post, daemon=True)
        t.start()

    def _now(self) -> str:
        return datetime.now(timezone.utc).isoformat()

    def send_session_start(self, session_key: str, correlation_id: Optional[str] = None) -> None:
        payload: dict = {
            "agent_id": self._agent_id,
            "session_key": session_key,
            "event_type": "session_start",
            "ts": self._now(),
        }
        if self._parent_agent_id and correlation_id:
            payload["parent_agent_id"] = self._parent_agent_id
            payload["correlation_id"] = correlation_id
        self._send(payload)

    def send_tool_call(
        self,
        session_key: str,
        tool_name: str,
        finding_category: Optional[str] = None,
        finding_severity: Optional[str] = None,
    ) -> None:
        self._send({
            "agent_id": self._agent_id,
            "session_key": session_key,
            "event_type": "tool_call",
            "tool_name": tool_name,
            "finding_category": finding_category,
            "finding_severity": finding_severity,
            "ts": self._now(),
        })

    def send_session_end(
        self,
        session_key: str,
        message_count: int,
        tool_call_count: int,
        threat_score: int,
        classification: str,
        findings_summary: dict,
    ) -> None:
        self._send({
            "agent_id": self._agent_id,
            "session_key": session_key,
            "event_type": "session_end",
            "message_count": message_count,
            "tool_call_count": tool_call_count,
            "threat_score": threat_score,
            "classification": classification,
            "findings_summary": findings_summary,
            "ts": self._now(),
        })


def create_child_session(parent_session_id: str) -> dict:
    """
    Create a correlation context for multi-agent calls.
    Pass the returned dict's 'id' as _guard_correlation_id in tool arguments.

    Example:
        ctx = create_child_session(guard_session.session_id)
        result = await mcp_client.call_tool("invoke_agent", {
            "task": "summarize Q1",
            "_guard_correlation_id": ctx["id"],
        })
    """
    import uuid
    return {
        "id": f"child_{uuid.uuid4().hex[:12]}",
        "parent_session_id": parent_session_id,
    }
