"""
Telemetry helpers для Humanized Stepan v2.7.2.

Забезпечує єдиний тег AGX_STEPAN_METRIC на всіх ключових лог-рядках
і PII-safe анонімізацію ідентифікаторів.

Grep у проді:
    grep "AGX_STEPAN_METRIC" /logs/gateway.log

Формат рядка:
    AGX_STEPAN_METRIC <event> key=value key2=value2

PII-safe:
- Ключі з pii_keys (default: {"user_id","chat_id"}) автоматично анонімізуються:
    user_id=h:3f9a12b4c7   (sha256 перших 10 hex-символів)
- Дає можливість корелювати події одного користувача без прямого витоку.
- Не є криптографічним захистом проти таргетованого знання.

Правила серіалізації:
- bool  → "true" / "false"
- int/float → str
- list  → елементи через кому
- dict  → компактний JSON
- None  → "null"
- Нічого з секретів/токенів не передавати у kv.
"""

from __future__ import annotations

import hashlib
import json
import logging
from typing import Any

TELEMETRY_TAG = "AGX_STEPAN_METRIC"

# Ключі, які автоматично анонімізуються у tlog()
_DEFAULT_PII_KEYS: frozenset[str] = frozenset({"user_id", "chat_id"})


def anonymize_id(value: str | None) -> str | None:
    """
    Повертає PII-safe псевдонім для ідентифікатора.

    Правила:
    - None → None
    - Пусте рядок → повернути як є (нема що хешувати)
    - Інакше: "h:" + sha256(value)[:10]

    Формат стабільний: завжди 12 символів ("h:" + 10 hex).
    Колізії теоретично можливі, але практично нереальні для user_id-просторів.

    Приклади:
        anonymize_id("123456789")  → "h:3f9a12b4c7"
        anonymize_id(None)         → None
        anonymize_id("")           → ""
    """
    if value is None:
        return None
    if not value:
        return value
    try:
        digest = hashlib.sha256(value.encode()).hexdigest()
        return f"h:{digest[:10]}"
    except Exception:
        return "h:error"


def _fmt_value(v: Any) -> str:
    if isinstance(v, bool):
        return str(v).lower()
    if isinstance(v, (int, float)):
        return str(v)
    if v is None:
        return "null"
    if isinstance(v, list):
        return ",".join(str(i) for i in v)
    if isinstance(v, dict):
        return json.dumps(v, ensure_ascii=False, separators=(",", ":"))
    return str(v)


def tlog(
    logger: logging.Logger,
    msg: str,
    level: int = logging.INFO,
    pii_keys: frozenset[str] | set[str] = _DEFAULT_PII_KEYS,
    **kv: Any,
) -> None:
    """
    Логує рядок з уніфікованим тегом AGX_STEPAN_METRIC і PII-safe анонімізацією.

    Приклади:
        tlog(logger, "depth", depth="light", reason="greeting")
        →  "AGX_STEPAN_METRIC depth depth=light reason=greeting"

        tlog(logger, "memory_save", user_id="123456789", ok=True)
        →  "AGX_STEPAN_METRIC memory_save user_id=h:3f9a12b4c7 ok=true"

    Ключі в pii_keys автоматично анонімізуються через anonymize_id().
    Безпечний: всі помилки форматування ігноруються — fallback без kv.
    """
    try:
        parts: list[str] = []
        for k, v in kv.items():
            if k in pii_keys:
                anon = anonymize_id(str(v) if v is not None else None)
                parts.append(f"{k}={_fmt_value(anon)}")
            else:
                parts.append(f"{k}={_fmt_value(v)}")
        kv_str = " ".join(parts)
        line = f"{TELEMETRY_TAG} {msg}"
        if kv_str:
            line = f"{line} {kv_str}"
    except Exception:
        line = f"{TELEMETRY_TAG} {msg}"
    logger.log(level, line)
