"""Anonymous, opt-in telemetry for usage statistics.

Telemetry is DISABLED by default. Users must explicitly opt in via:
  - Environment variable: BILGE_TELEMETRY=1
  - Config: bilge.yaml -> telemetry: enabled: true

Data collected (when opted in):
  - Command name (e.g., "profile", "run")
  - OS and Python version
  - GPU vendor (e.g., "nvidia", "amd", "apple", "none") — no specific model
  - BilgeAI version
  - Anonymous session ID (random UUID, not tied to user identity)

Data NOT collected:
  - IP address, username, hostname
  - File paths, dataset contents, model names
  - API keys, tokens, credentials
  - Any personally identifiable information
"""

from __future__ import annotations

import logging
import os
import uuid
from dataclasses import dataclass, field
from datetime import datetime, timezone
from pathlib import Path

logger = logging.getLogger(__name__)

TELEMETRY_ENV_VAR = "BILGE_TELEMETRY"
TELEMETRY_FILE = ".bilge/telemetry.json"


@dataclass
class TelemetryEvent:
    """A single telemetry event."""

    event: str  # e.g., "command_run"
    command: str  # e.g., "profile", "run"
    timestamp: str = field(default_factory=lambda: datetime.now(timezone.utc).isoformat())
    bilgeai_version: str = ""
    python_version: str = ""
    os_name: str = ""
    gpu_vendor: str = "none"
    session_id: str = ""


@dataclass
class TelemetryCollector:
    """Collects and stores anonymous telemetry events.

    Telemetry is opt-in only. No data is sent anywhere by default —
    events are stored locally in .bilge/telemetry.json.
    """

    enabled: bool = False
    session_id: str = field(default_factory=lambda: uuid.uuid4().hex[:12])
    events: list[TelemetryEvent] = field(default_factory=list)

    def record(self, command: str, gpu_vendor: str = "none") -> None:
        """Record a command usage event (only if telemetry is enabled)."""
        if not self.enabled:
            return

        import platform
        import sys

        from bilgeai import __version__

        event = TelemetryEvent(
            event="command_run",
            command=command,
            bilgeai_version=__version__,
            python_version=f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
            os_name=platform.system().lower(),
            gpu_vendor=gpu_vendor,
            session_id=self.session_id,
        )
        self.events.append(event)
        logger.debug("Telemetry event recorded: %s", command)

    def save(self, path: Path | None = None) -> None:
        """Save events to local JSON file."""
        if not self.enabled or not self.events:
            return

        import json

        target = path or Path.cwd() / TELEMETRY_FILE
        target.parent.mkdir(parents=True, exist_ok=True)

        existing = []
        if target.exists():
            try:
                existing = json.loads(target.read_text(encoding="utf-8"))
            except (json.JSONDecodeError, ValueError):
                existing = []

        from dataclasses import asdict

        new_events = [asdict(e) for e in self.events]
        existing.extend(new_events)

        target.write_text(
            json.dumps(existing, indent=2, ensure_ascii=False),
            encoding="utf-8",
        )
        logger.debug("Telemetry saved: %d events to %s", len(new_events), target)

    def get_summary(self) -> dict:
        """Get a summary of collected events."""
        if not self.events:
            return {"total_events": 0, "commands": {}}

        command_counts: dict[str, int] = {}
        for event in self.events:
            command_counts[event.command] = command_counts.get(event.command, 0) + 1

        return {
            "total_events": len(self.events),
            "commands": command_counts,
            "session_id": self.session_id,
        }


def is_telemetry_enabled() -> bool:
    """Check if telemetry is opted in via environment variable."""
    env_value = os.environ.get(TELEMETRY_ENV_VAR, "").strip().lower()
    return env_value in ("1", "true", "yes", "on")


def get_telemetry_collector() -> TelemetryCollector:
    """Create a telemetry collector based on opt-in status."""
    return TelemetryCollector(enabled=is_telemetry_enabled())
