"""Privacy data models -- Pydantic v2 schemas for privacy classification."""

from __future__ import annotations

from enum import Enum

from pydantic import BaseModel, Field


class PrivacyTier(str, Enum):
    """Privacy classification tier for request routing.

    PUBLIC: No PII detected; safe for cloud routing.
    PRIVATE: Contains PII (emails, phone numbers, names); local-only routing.
    SENSITIVE: High-risk PII (SSNs, credit cards, medical); encrypted local-only.
    """

    PUBLIC = "public"
    PRIVATE = "private"
    SENSITIVE = "sensitive"


class PrivacyClassification(BaseModel):
    """Result of classifying a request's privacy level."""

    tier: PrivacyTier
    pii_types_found: list[str] = Field(default_factory=list)
    pii_count: int = 0
    reasoning: str = ""
    scan_time_ms: float = 0.0


class PrivacySettings(BaseModel):
    """User-configurable privacy preferences."""

    allow_cloud_routing: bool = True
    """When True, requests with no PII can be routed to cloud backends."""

    privacy_mode: str = "standard"
    """Privacy mode: 'standard' (default), 'strict' (all local), 'paranoid' (encrypted local)."""

    custom_pii_patterns: dict[str, str] = Field(default_factory=dict)
    """User-defined regex patterns for additional PII types. Key=name, value=pattern."""

    redact_logs: bool = True
    """When True, PII is redacted from routing decision logs."""

    def effective_tier_override(self) -> PrivacyTier | None:
        """Return a forced tier based on privacy mode, or None for default behaviour."""
        if self.privacy_mode == "strict":
            return PrivacyTier.PRIVATE
        if self.privacy_mode == "paranoid":
            return PrivacyTier.SENSITIVE
        return None

    def allows_cloud(self, classification: PrivacyClassification) -> bool:
        """Return True if the given classification allows cloud routing under these settings."""
        if not self.allow_cloud_routing:
            return False
        override = self.effective_tier_override()
        if override is not None:
            return False
        return classification.tier == PrivacyTier.PUBLIC
