from typing import Optional, List, Iterator
from pydantic import BaseModel, Field, AnyUrl


class VulnerabilityReferences(BaseModel):
    vulnerability_id: Optional[str] = None
    advisories: Optional[List[AnyUrl]] = Field(default_factory=list)
    exploits: Optional[List[AnyUrl]] = Field(default_factory=list)
    reports: Optional[List[AnyUrl]] = Field(default_factory=list)
    other: Optional[List[AnyUrl]] = Field(default_factory=list)

    def extend(self, references: "VulnerabilityReferences"):
        self.advisories.extend(references.advisories)
        self.exploits.extend(references.exploits)
        self.reports.extend(references.reports)
        self.other.extend(references.other)

    def to_list(self) -> List[AnyUrl]:
        return self.advisories + self.exploits + self.reports + self.other

    def __len__(self):
        return len(self.to_list())

    def __iter__(self) -> Iterator[AnyUrl]:
        return iter(self.to_list())

    def __str__(self):
        ref_categories = [
            ("advisories", self.advisories),
            ("exploits", self.exploits),
            ("reports", self.reports),
            ("other", self.other)
        ]

        ref_details = [f"{len(ref)} {name}" for name, ref in ref_categories if ref]
        ref_str = f"{len(self)} references" + (" (" + ", ".join(ref_details) + ")" if ref_details else "")

        return ref_str
