import hashlib
import json
import os
from datetime import datetime, timezone
from pathlib import Path
from typing import Dict, Any, Union, Optional

from security.audit_trail import AuditTrail, OperationType

from .exceptions import NovyxStorageError


class TelemetryLogger:
    """
    Enterprise-only audit logging for SDK usage.

    Logs a Pulse event for each SDK call when NOVYX_TIER=enterprise.
    """

    def __init__(self, session_id: str, memory_dir: Optional[Union[str, Path]] = None):
        self.session_id = session_id
        self.tier = os.getenv("NOVYX_TIER", "").lower()
        self.memory_dir = Path(memory_dir or os.getenv("NOVYX_MEMORY_DIR", "memory"))
        self.audit_dir = self.memory_dir / ".audit"
        self._audit = None

        if self.tier == "enterprise":
            try:
                self._audit = AuditTrail(self.audit_dir, verify_on_load=False)
            except Exception as exc:
                raise NovyxStorageError(f"Failed to initialize audit trail: {exc}") from exc

    def _hash_payload(self, payload: Dict[str, Any]) -> str:
        content = json.dumps(payload, sort_keys=True, separators=(",", ":"))
        return hashlib.sha256(content.encode("utf-8")).hexdigest()

    def log_pulse(self, verb: str, payload: Dict[str, Any]) -> None:
        if self.tier != "enterprise":
            return

        if not self._audit:
            raise NovyxStorageError("Audit trail not initialized.")

        content_hash = self._hash_payload(payload)
        timestamp = datetime.now(timezone.utc).isoformat()
        self._audit.log(
            operation=OperationType.ACCESS.value,
            agent_id=self.session_id,
            artifact_id=f"pulse:{verb}",
            content_hash=content_hash,
            metadata={
                "verb": verb,
                "timestamp": timestamp,
                "payload": payload,
            },
        )
