from typing import Any

from pydantic import BaseModel, field_validator

from .package import Package
from .version import VersionPredicate


class Vulnerability(BaseModel):
    """Represents a vulnerability within an advisory."""

    package: Package
    vulnerable_version_range: list[VersionPredicate] = []
    first_patched_version: str | None = None

    @field_validator("vulnerable_version_range", mode="before")
    @classmethod
    def parse_vulnerable_version_range(cls, v: Any) -> list[VersionPredicate]:
        if not isinstance(v, str):
            raise ValueError(f"Invalid vulnerable version range: {v}")
        # Handle single predicate string
        if "," not in v:
            return [VersionPredicate.from_str(v)]
        # Handle comma-separated predicates
        return [
            VersionPredicate.from_str(predicate.strip()) for predicate in v.split(",")
        ]

    def __str__(self) -> str:
        patched = (
            f" → {self.first_patched_version}"
            if self.first_patched_version is not None
            else ""
        )
        version_range_str = (
            "[" + ", ".join(str(pred) for pred in self.vulnerable_version_range) + "]"
        )
        return f"{self.package}: {version_range_str}{patched}"

    def __repr__(self) -> str:
        version_range_str = (
            "[" + ", ".join(str(pred) for pred in self.vulnerable_version_range) + "]"
        )
        return (
            f"Vulnerability(package={self.package!r}, "
            f"vulnerable_version_range={version_range_str}, "
            f"first_patched_version={self.first_patched_version!r})"
        )
