"""All Pydantic v2 models — single source of truth, no logic."""

from enum import StrEnum
from typing import Any

from pydantic import BaseModel, Field


class Verdict(StrEnum):
    PASS = "PASS"
    WARN = "WARN"
    FAIL = "FAIL"


class Report(BaseModel):
    """Bug report loaded from disk, ready for triage."""

    raw_text: str
    source_path: str
    char_count: int



class AssetScope(BaseModel):
    include: list[str] = []
    exclude: list[str] = []


class Check(BaseModel):
    id: str
    hard_fail: bool = False
    config: dict[str, Any] = Field(default_factory=dict)


class CheckResult(BaseModel):
    check_id: str
    passed: bool
    reason: str
    prompt_tokens: int = Field(default=0, exclude=True)
    completion_tokens: int = Field(default=0, exclude=True)


class Policy(BaseModel):
    checks: list[Check] = Field(default_factory=list)


class ChecksResult(BaseModel):
    """Result of running policy checks. Primary output of the triage command."""

    checks: list[CheckResult]
    summary: str
    verdict: Verdict
    model_used: str
    prompt_tokens: int
    completion_tokens: int


class Program(BaseModel):
    name: str
    platform: str
    source: str  # URL of the original program page
    assets: AssetScope = Field(default_factory=AssetScope)
    ineligible_findings: list[str] = []
    required_report_sections: list[str] = []
    notes: list[str] = []

    def to_policy_text(self) -> str:
        """Render program as a policy text string for triage prompts."""
        def bullets(items: list[str]) -> str:
            return "\n".join(f"- {item}" for item in items) if items else "- (none specified)"

        parts = [f"# {self.name}", f"Platform: {self.platform}"]
        parts += ["\n## In-Scope Assets", bullets(self.assets.include)]
        parts += ["\n## Out-of-Scope Assets", bullets(self.assets.exclude)]
        if self.ineligible_findings:
            parts += ["\n## Ineligible Findings", bullets(self.ineligible_findings)]
        if self.required_report_sections:
            parts += ["\n## Required Report Sections", bullets(self.required_report_sections)]
        if self.notes:
            parts += ["\n## Notes", bullets(self.notes)]
        return "\n".join(parts)
