"""Data models for YAML Doctor."""

from __future__ import annotations

from dataclasses import dataclass, field
from enum import Enum


class Severity(str, Enum):
    CRITICAL = "critical"
    HIGH = "high"
    MEDIUM = "medium"
    LOW = "low"
    INFO = "info"


class FileType(str, Enum):
    KUBERNETES = "Kubernetes"
    HELM = "Helm"
    DOCKER_COMPOSE = "Docker Compose"
    GITHUB_ACTIONS = "GitHub Actions"
    GITLAB_CI = "GitLab CI"
    GENERIC_YAML = "YAML"
    UNKNOWN = "Unknown"


class Grade(str, Enum):
    A_PLUS = "A+"
    A = "A"
    B = "B"
    C = "C"
    D = "D"
    F = "F"


def grade_from_score(score: int) -> Grade:
    if score >= 95:
        return Grade.A_PLUS
    if score >= 85:
        return Grade.A
    if score >= 75:
        return Grade.B
    if score >= 65:
        return Grade.C
    if score >= 50:
        return Grade.D
    return Grade.F


@dataclass
class LintRule:
    rule_id: str
    category: str
    severity: Severity
    title: str
    description: str
    fix: str


@dataclass
class Finding:
    rule: LintRule
    line: int
    message: str
    path: str = ""
    fix_suggestion: str = ""


@dataclass
class LintResult:
    file_path: str
    file_type: FileType = FileType.UNKNOWN
    findings: list[Finding] = field(default_factory=list)
    documents: int = 0
    score: int = 100
    grade: Grade = Grade.A_PLUS
    valid_yaml: bool = True
    parse_error: str = ""

    @property
    def critical_count(self) -> int:
        return sum(1 for f in self.findings if f.rule.severity == Severity.CRITICAL)

    @property
    def high_count(self) -> int:
        return sum(1 for f in self.findings if f.rule.severity == Severity.HIGH)

    @property
    def medium_count(self) -> int:
        return sum(1 for f in self.findings if f.rule.severity == Severity.MEDIUM)

    @property
    def low_count(self) -> int:
        return sum(1 for f in self.findings if f.rule.severity == Severity.LOW)

    @property
    def info_count(self) -> int:
        return sum(1 for f in self.findings if f.rule.severity == Severity.INFO)

    @property
    def total_issues(self) -> int:
        return len([f for f in self.findings if f.rule.severity != Severity.INFO])

    @property
    def passed(self) -> bool:
        return self.valid_yaml and self.critical_count == 0 and self.high_count == 0


@dataclass
class ScanResult:
    """Result of scanning multiple files."""

    files: list[LintResult] = field(default_factory=list)
    total_files: int = 0
    total_findings: int = 0
    overall_score: int = 100
    overall_grade: Grade = Grade.A_PLUS

    @property
    def passed_files(self) -> int:
        return sum(1 for f in self.files if f.passed)

    @property
    def failed_files(self) -> int:
        return self.total_files - self.passed_files

    @property
    def critical_total(self) -> int:
        return sum(f.critical_count for f in self.files)

    @property
    def high_total(self) -> int:
        return sum(f.high_count for f in self.files)
