"""
Shared ProofKit helpers for receipt attestation.

These utilities allow any receipt to attach a ProofKit attestation bundle
without duplicating signing logic across domains.
"""

from __future__ import annotations

import logging
import os
from typing import Any, Dict, Optional

from tools.proofkit import ProofKit

logger = logging.getLogger("loom.receipts.proofkit")
proofkit = ProofKit()

_KEY_CACHE: Optional[Optional[bytes]] = None
_KEY_ENV = "PROOFKIT_HMAC_KEY"


def _resolve_signing_key(explicit_key: Optional[bytes]) -> Optional[bytes]:
    """Return the explicit key when provided, otherwise fall back to env."""

    global _KEY_CACHE
    if explicit_key is not None:
        return explicit_key

    if _KEY_CACHE is not None:
        return _KEY_CACHE

    token = os.getenv(_KEY_ENV, "").strip()
    if not token:
        _KEY_CACHE = None
        return None

    _KEY_CACHE = token.encode("utf-8")
    logger.info("ProofKit signing enabled via %s", _KEY_ENV)
    return _KEY_CACHE


def generate_attestation(
    receipt: Any,
    *,
    key: Optional[bytes] = None,
    algorithm: str = "hmac-sha256",
    receipt_mode: Optional[str] = None,
    log: Optional[logging.Logger] = None,
) -> Dict[str, Any]:
    """
    Produce a ProofKit attestation for the provided receipt instance.

    Returns the attestation mapping when signing succeeds, or an empty dict if
    signing is disabled/unsupported.
    """

    logger_obj = log or logger
    mode = receipt_mode or getattr(receipt, "receipt_mode", "signed")
    if mode != "signed":
        return {}

    signing_key = _resolve_signing_key(key)
    if not signing_key:
        logger_obj.debug("ProofKit key unavailable; skipping attestation for %s", getattr(receipt, "receipt_id", "receipt"))
        return {}

    if hasattr(receipt, "to_dict"):
        payload = receipt.to_dict()
    elif hasattr(receipt, "model_dump"):
        payload = receipt.model_dump(mode="json")
    elif hasattr(receipt, "dict"):
        payload = receipt.dict()
    else:
        payload = dict(receipt)

    payload = dict(payload)
    payload.pop("attestation", None)

    try:
        signed = proofkit.sign_receipt(payload, signing_key, algorithm)
    except Exception:
        logger_obj.exception("Failed to sign receipt %s with ProofKit", getattr(receipt, "receipt_id", "receipt"))
        return {}

    return signed.get("attestation", {})


__all__ = ["generate_attestation"]
