# coding: utf-8

"""
    Verity471 Unified API

      - creds: 1.0.0
  - girs: 1.0.0
  - indicators: 1.0.0
  - malware: 1.0.0
  - reports: 1.0.0
  - sources: 1.0.0


    The version of the OpenAPI document: 1.0.0
    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, StrictBool, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from verity471.models.classification import Classification
from verity471.models.confidence import Confidence
from verity471.models.entities import Entities
from verity471.models.links import Links
from verity471.models.report_content import ReportContent
from verity471.models.reports_victim_response import ReportsVictimResponse
from verity471.models.sources_response import SourcesResponse
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 BreachAlertResponse(BaseModel):
    """
    BreachAlertResponse
    """ # noqa: E501
    id: StrictStr = Field(description="Unique identifier of the report")
    type: StrictStr = Field(description="Type of the report")
    title: StrictStr = Field(description="Title of the report")
    creation_ts: StrictStr = Field(description="Timestamp when the report was published first time")
    released_ts: StrictStr = Field(description="Timestamp when the report was published last time")
    last_updated_ts: StrictStr = Field(description="Report last update datetime")
    information_ts: StrictStr = Field(description="Timestamp of the information contained in the report")
    entities: Optional[List[Entities]] = Field(default=None, description="List of entities mentioned in the report")
    sources: Optional[List[SourcesResponse]] = Field(default=None, description="List of sources referenced in the report")
    classification: Classification
    victims: Optional[List[ReportsVictimResponse]] = Field(default=None, description="List of purported victims mentioned in the report")
    actor_or_group: StrictStr = Field(description="Actor or group name")
    body: Optional[StrictStr] = Field(default=None, description="Main content body of the report. This field may be omitted in streaming responses when content exceeds the configured maximum size; fetch full report by ID if needed.")
    is_sensitive_source: Optional[StrictBool] = Field(default=None, description="Indicates if the report contains sensitive source derived information")
    confidence: Confidence
    is_truncated: Optional[StrictBool] = Field(default=None, description="True when the body field was omitted due to exceeding size limit; fetch full report by ID if needed")
    links: Links
    related_reports: Optional[List[ReportContent]] = Field(default=None, description="List of related reports connected to this report")
    __properties: ClassVar[List[str]] = ["id", "type", "title", "creation_ts", "released_ts", "last_updated_ts", "information_ts", "entities", "sources", "classification", "victims", "actor_or_group", "body", "is_sensitive_source", "confidence", "is_truncated", "links", "related_reports"]

    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 BreachAlertResponse 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 each item in entities (list)
        _items = []
        if self.entities:
            for _item_entities in self.entities:
                if _item_entities:
                    _items.append(_item_entities.to_dict())
            _dict['entities'] = _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
        # 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 victims (list)
        _items = []
        if self.victims:
            for _item_victims in self.victims:
                if _item_victims:
                    _items.append(_item_victims.to_dict())
            _dict['victims'] = _items
        # override the default output from pydantic by calling `to_dict()` of confidence
        if self.confidence:
            _dict['confidence'] = self.confidence.to_dict()
        # 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 related_reports (list)
        _items = []
        if self.related_reports:
            for _item_related_reports in self.related_reports:
                if _item_related_reports:
                    _items.append(_item_related_reports.to_dict())
            _dict['related_reports'] = _items
        return _dict

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

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

        _obj = cls.model_validate({
            "id": obj.get("id"),
            "type": obj.get("type"),
            "title": obj.get("title"),
            "creation_ts": obj.get("creation_ts"),
            "released_ts": obj.get("released_ts"),
            "last_updated_ts": obj.get("last_updated_ts"),
            "information_ts": obj.get("information_ts"),
            "entities": [Entities.from_dict(_item) for _item in obj["entities"]] if obj.get("entities") is not None else None,
            "sources": [SourcesResponse.from_dict(_item) for _item in obj["sources"]] if obj.get("sources") is not None else None,
            "classification": Classification.from_dict(obj["classification"]) if obj.get("classification") is not None else None,
            "victims": [ReportsVictimResponse.from_dict(_item) for _item in obj["victims"]] if obj.get("victims") is not None else None,
            "actor_or_group": obj.get("actor_or_group"),
            "body": obj.get("body"),
            "is_sensitive_source": obj.get("is_sensitive_source"),
            "confidence": Confidence.from_dict(obj["confidence"]) if obj.get("confidence") is not None else None,
            "is_truncated": obj.get("is_truncated"),
            "links": Links.from_dict(obj["links"]) if obj.get("links") is not None else None,
            "related_reports": [ReportContent.from_dict(_item) for _item in obj["related_reports"]] if obj.get("related_reports") is not None else None
        })
        return _obj


