"""
VasperaGuard data models.
"""

from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional
from datetime import datetime


@dataclass
class AgentContext:
    """Context about the AI agent making the request."""

    environment: Optional[str] = None  # development, staging, production
    project: Optional[str] = None
    user_id: Optional[str] = None
    session_id: Optional[str] = None
    working_directory: Optional[str] = None

    def to_dict(self) -> Dict[str, Any]:
        return {
            "environment": self.environment,
            "project": self.project,
            "user_id": self.user_id,
            "session_id": self.session_id,
            "working_directory": self.working_directory,
        }


@dataclass
class CheckResult:
    """Result from a safety check."""

    check_id: str
    allowed: bool
    blocked: bool
    requires_approval: bool
    risk_score: float
    risk_level: str  # low, medium, high, critical
    reason: Optional[str] = None
    warnings: List[str] = field(default_factory=list)
    suggestions: List[str] = field(default_factory=list)
    approval_url: Optional[str] = None

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "CheckResult":
        return cls(
            check_id=data["check_id"],
            allowed=data["allowed"],
            blocked=data["blocked"],
            requires_approval=data["requires_approval"],
            risk_score=data["risk_score"],
            risk_level=data["risk_level"],
            reason=data.get("reason"),
            warnings=data.get("warnings", []),
            suggestions=data.get("suggestions", []),
            approval_url=data.get("approval_url"),
        )

    @property
    def is_safe(self) -> bool:
        """Returns True if the command is safe to execute."""
        return self.allowed and not self.blocked

    @property
    def needs_human(self) -> bool:
        """Returns True if human approval is required."""
        return self.requires_approval


@dataclass
class ApprovalResult:
    """Result from an approval request."""

    approval_id: str
    status: str  # pending, approved, denied, expired
    check_id: str
    command: str
    expires_at: str
    approve_url: str
    deny_url: str

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "ApprovalResult":
        return cls(
            approval_id=data["approval_id"],
            status=data["status"],
            check_id=data["check_id"],
            command=data["command"],
            expires_at=data["expires_at"],
            approve_url=data["approve_url"],
            deny_url=data["deny_url"],
        )

    @property
    def is_pending(self) -> bool:
        return self.status == "pending"

    @property
    def is_approved(self) -> bool:
        return self.status == "approved"

    @property
    def is_denied(self) -> bool:
        return self.status == "denied"


@dataclass
class PolicyRule:
    """A single rule in a policy."""

    pattern: str
    action: str  # block, require_approval, warn, allow
    reason: Optional[str] = None

    def to_dict(self) -> Dict[str, Any]:
        return {
            "pattern": self.pattern,
            "action": self.action,
            "reason": self.reason,
        }


@dataclass
class Policy:
    """A safety policy."""

    policy_id: str
    name: str
    description: Optional[str] = None
    rules: List[PolicyRule] = field(default_factory=list)
    environments: Optional[List[str]] = None
    created_at: Optional[str] = None

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "Policy":
        rules = [
            PolicyRule(
                pattern=r["pattern"],
                action=r["action"],
                reason=r.get("reason"),
            )
            for r in data.get("rules", [])
        ]
        return cls(
            policy_id=data["policy_id"],
            name=data["name"],
            description=data.get("description"),
            rules=rules,
            environments=data.get("environments"),
            created_at=data.get("created_at"),
        )


@dataclass
class AuditEntry:
    """An entry in the audit log."""

    id: str
    timestamp: str
    agent_id: str
    command: str
    check_result: str  # allowed, blocked, pending_approval
    risk_score: float
    risk_level: str
    context: Optional[Dict[str, Any]] = None
    approval_id: Optional[str] = None
    executed: bool = False

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "AuditEntry":
        return cls(
            id=data["id"],
            timestamp=data["timestamp"],
            agent_id=data["agent_id"],
            command=data["command"],
            check_result=data["check_result"],
            risk_score=data["risk_score"],
            risk_level=data["risk_level"],
            context=data.get("context"),
            approval_id=data.get("approval_id"),
            executed=data.get("executed", False),
        )
