"""Core data models for Domain Vigil."""

from dataclasses import dataclass, field
from enum import Enum
from typing import List, Optional, Dict, Any


class Severity(Enum):
    """Severity levels for deal-breakers."""
    CRITICAL = "critical"
    HIGH = "high"
    MEDIUM = "medium"
    LOW = "low"


@dataclass
class DealBreaker:
    """A critical constraint that must never be violated.

    Deal-breakers represent non-negotiable rules about persona behavior.
    They are the core of domain validation.

    Attributes:
        id: Unique identifier for this deal-breaker
        description: Human-readable description of the constraint
        severity: How critical this violation would be
        examples: Optional examples of violations
        learned_patterns: Patterns learned by LLM from codebase analysis
    """
    id: str
    description: str
    severity: Severity = Severity.CRITICAL
    examples: List[str] = field(default_factory=list)
    learned_patterns: List[Dict[str, Any]] = field(default_factory=list)


@dataclass
class Ability:
    """Something a persona can do.

    Abilities describe the actions and capabilities of a persona.
    They help scope validation to relevant code.

    Attributes:
        id: Unique identifier for this ability
        description: Human-readable description of the ability
        examples: Optional examples of this ability in action
    """
    id: str
    description: str
    examples: List[str] = field(default_factory=list)


@dataclass
class Persona:
    """A persona with behavioral constraints.

    Personas represent users, roles, or entities in your domain.
    They define what matters most about how that entity behaves.

    Attributes:
        name: The persona name (e.g., "student", "teacher", "admin")
        description: Human-readable description of the persona
        deal_breakers: Critical constraints that must never be violated
        abilities: What this persona can do
        metadata: Additional context for LLM analysis
    """
    name: str
    description: str = ""
    deal_breakers: List[DealBreaker] = field(default_factory=list)
    abilities: List[Ability] = field(default_factory=list)
    metadata: Dict[str, Any] = field(default_factory=dict)

    def get_deal_breaker(self, deal_breaker_id: str) -> Optional[DealBreaker]:
        """Get a deal-breaker by ID."""
        for db in self.deal_breakers:
            if db.id == deal_breaker_id:
                return db
        return None


@dataclass
class ValidationViolation:
    """A detected violation of a deal-breaker.

    Attributes:
        deal_breaker_id: The deal-breaker that was violated
        file_path: Path to the file containing the violation
        line_number: Line number where violation occurs
        code_snippet: The offending code
        explanation: LLM explanation of why this is a violation
        confidence: Confidence score (0.0-1.0)
    """
    deal_breaker_id: str
    file_path: str
    line_number: int
    code_snippet: str
    explanation: str
    confidence: float


@dataclass
class ValidationResult:
    """Result of validating code against a persona.

    Attributes:
        persona_name: The persona that was validated
        files_analyzed: Number of files analyzed
        violations: List of detected violations
        passed: Whether validation passed (no critical violations)
    """
    persona_name: str
    files_analyzed: int
    violations: List[ValidationViolation] = field(default_factory=list)
    passed: bool = True

    @property
    def critical_violations(self) -> List[ValidationViolation]:
        """Get only critical violations."""
        return [v for v in self.violations if v.confidence >= 0.8]

    @property
    def warning_violations(self) -> List[ValidationViolation]:
        """Get warning-level violations."""
        return [v for v in self.violations if 0.5 <= v.confidence < 0.8]
