"""Privacy manifest -- machine-readable declaration of what LLMHosts does.

Generated at startup based on actual configuration. Users can verify
every claim by inspecting their config and comparing.
"""

from __future__ import annotations

import logging
from datetime import datetime, timezone
from pathlib import Path
from typing import TYPE_CHECKING, Any

from pydantic import BaseModel, Field

if TYPE_CHECKING:
    from llmhosts.config import LLMHostsConfig

logger = logging.getLogger(__name__)


class PrivacyManifest(BaseModel):
    """Machine-readable privacy manifest."""

    version: str = "1.0"
    generated: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    data_collection: dict[str, Any] = Field(
        default_factory=lambda: {
            "telemetry": False,
            "crash_reports": False,
            "usage_analytics": False,
            "note": "Zero data leaves your machine unless you explicitly configure cloud APIs or tunnels",
        }
    )
    network_connections: list[dict[str, str]] = Field(default_factory=list)
    local_storage: list[dict[str, Any]] = Field(default_factory=list)
    gpu_usage: dict[str, Any] = Field(
        default_factory=lambda: {
            "purpose": "LLM inference only",
            "mining": False,
            "third_party_compute": False,
            "note": (
                "GPU is used exclusively for your own inference requests. "
                "Never for mining, never shared without explicit opt-in via Hive Mode."
            ),
        }
    )
    permissions_required: list[str] = Field(
        default_factory=lambda: [
            "network (localhost + configured APIs)",
            "disk (config + cache + audit)",
        ]
    )
    permissions_never_used: list[str] = Field(
        default_factory=lambda: [
            "camera",
            "microphone",
            "contacts",
            "location",
            "clipboard (read)",
            "screen recording",
        ]
    )

    @classmethod
    def generate(cls, config: LLMHostsConfig | None = None) -> PrivacyManifest:
        """Generate manifest from current configuration."""
        manifest = cls()
        manifest.network_connections = cls._detect_network_connections(config)
        manifest.local_storage = cls._detect_local_storage()
        return manifest

    @staticmethod
    def _detect_network_connections(config: LLMHostsConfig | None) -> list[dict[str, str]]:
        """Detect what network connections LLMHosts will make based on config."""
        connections: list[dict[str, str]] = []

        # Always: Ollama (local)
        ollama_host = "http://127.0.0.1:11434"
        if config and config.ollama:
            ollama_host = config.ollama.host
        connections.append(
            {
                "destination": ollama_host,
                "purpose": "Ollama inference",
                "direction": "outbound_local",
            }
        )

        # Cloud APIs (only if keys are configured)
        if config:
            try:
                from llmhosts.keys.manager import KeyManager

                mgr = KeyManager()
                providers = mgr.list_providers()
                api_endpoints = {
                    "openai": "api.openai.com",
                    "anthropic": "api.anthropic.com",
                    "google": "generativelanguage.googleapis.com",
                    "cohere": "api.cohere.com",
                    "mistral": "api.mistral.ai",
                }
                for p in providers:
                    endpoint = api_endpoints.get(p.provider, f"api.{p.provider}.com")
                    connections.append(
                        {
                            "destination": endpoint,
                            "purpose": f"Cloud API ({p.provider}, user-configured BYOK)",
                            "direction": "outbound_internet",
                            "data_sent": "prompts and model parameters",
                            "condition": "only when cloud routing is active",
                        }
                    )
            except Exception:
                pass  # No keys configured or key manager unavailable

        return connections

    @staticmethod
    def _detect_local_storage() -> list[dict[str, Any]]:
        """Detect what local storage LLMHosts uses."""
        home = Path.home()
        return [
            {
                "path": str(home / ".config" / "llmhosts"),
                "purpose": "Configuration and encrypted keys",
                "encrypted": True,
            },
            {
                "path": str(home / ".local" / "share" / "llmhosts" / "audit.db"),
                "purpose": "Local audit log (request history, routing decisions)",
                "encrypted": False,
            },
            {
                "path": str(home / ".local" / "share" / "llmhosts" / "cache"),
                "purpose": "Semantic cache (cached LLM responses)",
                "encrypted": False,
            },
        ]

    def to_json(self) -> str:
        """Serialize to pretty-printed JSON."""
        return self.model_dump_json(indent=2)

    def to_dict(self) -> dict[str, Any]:
        """Serialize to dictionary."""
        return self.model_dump(mode="json")
