# coding: utf-8

"""
    Verity471 Unified API

      - creds: 1.0.1
  - indicators: 1.0.0
  - malware: 1.0.0
  - reports: 1.0.0
  - sources: 1.0.2
  - actors: 1.0.1
  - watchers: 1.0.0
  - observables: 1.0.0
  - entities: 1.0.0
  - girs: 1.0.0


    The version of the OpenAPI document: 1.1.1
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json


from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from verity471.models.activity import Activity
from verity471.models.activity_location import ActivityLocation
from verity471.models.classification import Classification
from verity471.models.cve_source import CveSource
from verity471.models.cvss import Cvss
from verity471.models.exploit_status import ExploitStatus
from verity471.models.interest_level import InterestLevel
from verity471.models.link1 import Link1
from verity471.models.links import Links
from verity471.models.patch_status import PatchStatus
from verity471.models.poc import Poc
from verity471.models.risk_level import RiskLevel
from verity471.models.vulnerability_status import VulnerabilityStatus
from typing import Optional, Set, TYPE_CHECKING
from typing_extensions import Self

if TYPE_CHECKING:
    # Only for type checkers; does not run at runtime.
    from verity471.verity_stix import STIXMapperSettings


class VulnerabilitiesReportDetailsResponse(BaseModel):
    """
    Minimal schema for a vulnerability report response with keys, types, and descriptions
    """ # noqa: E501
    activity: Activity
    activity_location: Optional[List[ActivityLocation]] = Field(default=None, description="List of locations where activity related to the vulnerability has been observed")
    aliases: Optional[List[StrictStr]] = Field(default=None, description="List of alternative names or identifiers for the vulnerability")
    body: Optional[StrictStr] = Field(default=None, description="HTML formatted summary of the vulnerability")
    classification: Classification
    counter_measure_links: Optional[List[Link1]] = Field(default=None, description="List of titled URLs to Counter Measures related to the vulnerability")
    counter_measures_html: Optional[StrictStr] = Field(default=None, description="HTML formatted summary of countermeasures for the vulnerability")
    creation_ts: StrictStr = Field(description="Timestamp when the report was published first time")
    cve_type: StrictStr = Field(description="Type of CVE, for example: Buffer overflow, Privilege escalation, Memory corruption, etc")
    cvss: Optional[List[Cvss]] = Field(default=None, description="List of CVSS scores associated with the vulnerability")
    exploit_status: Optional[List[ExploitStatus]] = Field(default=None, description="List of exploitation status details for the vulnerability")
    id: StrictStr = Field(description="Unique identifier of the report")
    interest_level: Optional[List[InterestLevel]] = Field(default=None, description="List of levels of interest related to the vulnerability")
    last_updated_ts: StrictStr = Field(description="Timestamp of last report update")
    links: Links
    name: StrictStr = Field(description="Name of the vulnerability")
    patch_links: Optional[List[Link1]] = Field(default=None, description="List of titled URLs to Patches related to the vulnerability")
    patch_status: Optional[PatchStatus] = None
    poc: Optional[Poc] = None
    poc_links: Optional[List[Link1]] = Field(default=None, description="List of titled URLs to Proofs of Concept related to the vulnerability")
    product_name: StrictStr = Field(description="Name of the product of the affected software")
    released_ts: StrictStr = Field(description="Timestamp when the report was published last time")
    risk_level: RiskLevel
    sort_priority: Optional[StrictInt] = Field(default=None, description="Priority used for sorting vulnerability reports")
    sources: Optional[List[CveSource]] = Field(default=None, description="List of sources referenced in the report")
    status: VulnerabilityStatus
    type: StrictStr = Field(description="Type of the report")
    underground_activity_summary_html: Optional[StrictStr] = Field(default=None, description="HTML formatted summary of underground activity related to the vulnerability")
    vendor_name: StrictStr = Field(description="Name of the vendor of the affected software")
    __properties: ClassVar[List[str]] = ["activity", "activity_location", "aliases", "body", "classification", "counter_measure_links", "counter_measures_html", "creation_ts", "cve_type", "cvss", "exploit_status", "id", "interest_level", "last_updated_ts", "links", "name", "patch_links", "patch_status", "poc", "poc_links", "product_name", "released_ts", "risk_level", "sort_priority", "sources", "status", "type", "underground_activity_summary_html", "vendor_name"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_stix(self, settings: Optional["STIXMapperSettings"] = None):
        try:
            from verity471.verity_stix.mappers.common import StixMapper
        except ImportError as e:
            raise ImportError(
                "STIX support is an optional feature. "
                "Install with: pip install 'verity471[stix]'"
            ) from e
        stix_mapper = StixMapper(settings)
        return stix_mapper.map(self.to_dict())

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of VulnerabilitiesReportDetailsResponse from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of activity
        if self.activity:
            _dict['activity'] = self.activity.to_dict()
        # override the default output from pydantic by calling `to_dict()` of classification
        if self.classification:
            _dict['classification'] = self.classification.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in counter_measure_links (list)
        _items = []
        if self.counter_measure_links:
            for _item_counter_measure_links in self.counter_measure_links:
                if _item_counter_measure_links:
                    _items.append(_item_counter_measure_links.to_dict())
            _dict['counter_measure_links'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in cvss (list)
        _items = []
        if self.cvss:
            for _item_cvss in self.cvss:
                if _item_cvss:
                    _items.append(_item_cvss.to_dict())
            _dict['cvss'] = _items
        # override the default output from pydantic by calling `to_dict()` of links
        if self.links:
            _dict['links'] = self.links.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in patch_links (list)
        _items = []
        if self.patch_links:
            for _item_patch_links in self.patch_links:
                if _item_patch_links:
                    _items.append(_item_patch_links.to_dict())
            _dict['patch_links'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in poc_links (list)
        _items = []
        if self.poc_links:
            for _item_poc_links in self.poc_links:
                if _item_poc_links:
                    _items.append(_item_poc_links.to_dict())
            _dict['poc_links'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in sources (list)
        _items = []
        if self.sources:
            for _item_sources in self.sources:
                if _item_sources:
                    _items.append(_item_sources.to_dict())
            _dict['sources'] = _items
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of VulnerabilitiesReportDetailsResponse from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "activity": Activity.from_dict(obj["activity"]) if obj.get("activity") is not None else None,
            "activity_location": obj.get("activity_location"),
            "aliases": obj.get("aliases"),
            "body": obj.get("body"),
            "classification": Classification.from_dict(obj["classification"]) if obj.get("classification") is not None else None,
            "counter_measure_links": [Link1.from_dict(_item) for _item in obj["counter_measure_links"]] if obj.get("counter_measure_links") is not None else None,
            "counter_measures_html": obj.get("counter_measures_html"),
            "creation_ts": obj.get("creation_ts"),
            "cve_type": obj.get("cve_type"),
            "cvss": [Cvss.from_dict(_item) for _item in obj["cvss"]] if obj.get("cvss") is not None else None,
            "exploit_status": obj.get("exploit_status"),
            "id": obj.get("id"),
            "interest_level": obj.get("interest_level"),
            "last_updated_ts": obj.get("last_updated_ts"),
            "links": Links.from_dict(obj["links"]) if obj.get("links") is not None else None,
            "name": obj.get("name"),
            "patch_links": [Link1.from_dict(_item) for _item in obj["patch_links"]] if obj.get("patch_links") is not None else None,
            "patch_status": obj.get("patch_status"),
            "poc": obj.get("poc"),
            "poc_links": [Link1.from_dict(_item) for _item in obj["poc_links"]] if obj.get("poc_links") is not None else None,
            "product_name": obj.get("product_name"),
            "released_ts": obj.get("released_ts"),
            "risk_level": obj.get("risk_level"),
            "sort_priority": obj.get("sort_priority"),
            "sources": [CveSource.from_dict(_item) for _item in obj["sources"]] if obj.get("sources") is not None else None,
            "status": obj.get("status"),
            "type": obj.get("type"),
            "underground_activity_summary_html": obj.get("underground_activity_summary_html"),
            "vendor_name": obj.get("vendor_name")
        })
        return _obj


