# coding: utf-8

"""
Perigon API

The Perigon API provides access to comprehensive news and web content data. To use the API, simply sign up for a Perigon Business Solutions account to obtain your API key. Your available features may vary based on your plan. See the Authentication section for details on how to use your API key.

The version of the OpenAPI document: 1.0.0
Contact: data@perigon.io
Generated by OpenAPI Generator (https://openapi-generator.tech)

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


from __future__ import annotations

import json
import pprint
import re  # noqa: F401
from typing import Any, ClassVar, Dict, List, Optional, Set

from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
from typing_extensions import Self

from perigon.models.category_holder import CategoryHolder
from perigon.models.company_count import CompanyCount
from perigon.models.company_holder import CompanyHolder
from perigon.models.key_point import KeyPoint
from perigon.models.location_count import LocationCount
from perigon.models.location_holder import LocationHolder
from perigon.models.person_count import PersonCount
from perigon.models.person_holder import PersonHolder
from perigon.models.question import Question
from perigon.models.record_stat_holder import RecordStatHolder
from perigon.models.sentiment_holder import SentimentHolder
from perigon.models.source_holder import SourceHolder
from perigon.models.topic_holder import TopicHolder


class NewsCluster(BaseModel):
    """
    NewsCluster
    """  # noqa: E501

    created_at: Optional[StrictStr] = Field(default=None, alias="createdAt")
    updated_at: Optional[StrictStr] = Field(default=None, alias="updatedAt")
    initialized_at: Optional[StrictStr] = Field(default=None, alias="initializedAt")
    id: Optional[StrictStr] = None
    duplicate_of: Optional[StrictStr] = Field(default=None, alias="duplicateOf")
    slug: Optional[StrictStr] = None
    name: Optional[StrictStr] = None
    summary: Optional[StrictStr] = None
    short_summary: Optional[StrictStr] = Field(default=None, alias="shortSummary")
    summary_references: Optional[List[StrictStr]] = Field(
        default=None, alias="summaryReferences"
    )
    image_source: Optional[SourceHolder] = Field(default=None, alias="imageSource")
    image_url: Optional[StrictStr] = Field(default=None, alias="imageUrl")
    key_points: Optional[List[KeyPoint]] = Field(default=None, alias="keyPoints")
    questions: Optional[List[Question]] = None
    unique_sources: Optional[List[StrictStr]] = Field(
        default=None, alias="uniqueSources"
    )
    selected_articles: Optional[List[Article]] = Field(
        default=None, alias="selectedArticles"
    )
    sentiment: Optional[SentimentHolder] = None
    unique_count: Optional[StrictInt] = Field(default=None, alias="uniqueCount")
    reprint_count: Optional[StrictInt] = Field(default=None, alias="reprintCount")
    total_count: Optional[StrictInt] = Field(default=None, alias="totalCount")
    countries: Optional[List[RecordStatHolder]] = None
    top_countries: Optional[List[StrictStr]] = Field(default=None, alias="topCountries")
    topics: Optional[List[RecordStatHolder]] = None
    top_topics: Optional[List[TopicHolder]] = Field(default=None, alias="topTopics")
    categories: Optional[List[RecordStatHolder]] = None
    top_categories: Optional[List[CategoryHolder]] = Field(
        default=None, alias="topCategories"
    )
    taxonomies: Optional[List[RecordStatHolder]] = None
    top_taxonomies: Optional[List[CategoryHolder]] = Field(
        default=None, alias="topTaxonomies"
    )
    people: Optional[List[PersonCount]] = None
    top_people: Optional[List[PersonHolder]] = Field(default=None, alias="topPeople")
    companies: Optional[List[CompanyCount]] = None
    top_companies: Optional[List[CompanyHolder]] = Field(
        default=None, alias="topCompanies"
    )
    locations: Optional[List[LocationCount]] = None
    top_locations: Optional[List[LocationHolder]] = Field(
        default=None, alias="topLocations"
    )
    highlights: Optional[Dict[str, List[StrictStr]]] = None
    __properties: ClassVar[List[str]] = [
        "createdAt",
        "updatedAt",
        "initializedAt",
        "id",
        "duplicateOf",
        "slug",
        "name",
        "summary",
        "shortSummary",
        "summaryReferences",
        "imageSource",
        "imageUrl",
        "keyPoints",
        "questions",
        "uniqueSources",
        "selectedArticles",
        "sentiment",
        "uniqueCount",
        "reprintCount",
        "totalCount",
        "countries",
        "topCountries",
        "topics",
        "topTopics",
        "categories",
        "topCategories",
        "taxonomies",
        "topTaxonomies",
        "people",
        "topPeople",
        "companies",
        "topCompanies",
        "locations",
        "topLocations",
        "highlights",
    ]

    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_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 NewsCluster 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 image_source
        if self.image_source:
            _dict["imageSource"] = self.image_source.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in key_points (list)
        _items = []
        if self.key_points:
            for _item_key_points in self.key_points:
                if _item_key_points:
                    _items.append(_item_key_points.to_dict())
            _dict["keyPoints"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in questions (list)
        _items = []
        if self.questions:
            for _item_questions in self.questions:
                if _item_questions:
                    _items.append(_item_questions.to_dict())
            _dict["questions"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in selected_articles (list)
        _items = []
        if self.selected_articles:
            for _item_selected_articles in self.selected_articles:
                if _item_selected_articles:
                    _items.append(_item_selected_articles.to_dict())
            _dict["selectedArticles"] = _items
        # override the default output from pydantic by calling `to_dict()` of sentiment
        if self.sentiment:
            _dict["sentiment"] = self.sentiment.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in countries (list)
        _items = []
        if self.countries:
            for _item_countries in self.countries:
                if _item_countries:
                    _items.append(_item_countries.to_dict())
            _dict["countries"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in topics (list)
        _items = []
        if self.topics:
            for _item_topics in self.topics:
                if _item_topics:
                    _items.append(_item_topics.to_dict())
            _dict["topics"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_topics (list)
        _items = []
        if self.top_topics:
            for _item_top_topics in self.top_topics:
                if _item_top_topics:
                    _items.append(_item_top_topics.to_dict())
            _dict["topTopics"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in categories (list)
        _items = []
        if self.categories:
            for _item_categories in self.categories:
                if _item_categories:
                    _items.append(_item_categories.to_dict())
            _dict["categories"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_categories (list)
        _items = []
        if self.top_categories:
            for _item_top_categories in self.top_categories:
                if _item_top_categories:
                    _items.append(_item_top_categories.to_dict())
            _dict["topCategories"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in taxonomies (list)
        _items = []
        if self.taxonomies:
            for _item_taxonomies in self.taxonomies:
                if _item_taxonomies:
                    _items.append(_item_taxonomies.to_dict())
            _dict["taxonomies"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_taxonomies (list)
        _items = []
        if self.top_taxonomies:
            for _item_top_taxonomies in self.top_taxonomies:
                if _item_top_taxonomies:
                    _items.append(_item_top_taxonomies.to_dict())
            _dict["topTaxonomies"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in people (list)
        _items = []
        if self.people:
            for _item_people in self.people:
                if _item_people:
                    _items.append(_item_people.to_dict())
            _dict["people"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_people (list)
        _items = []
        if self.top_people:
            for _item_top_people in self.top_people:
                if _item_top_people:
                    _items.append(_item_top_people.to_dict())
            _dict["topPeople"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in companies (list)
        _items = []
        if self.companies:
            for _item_companies in self.companies:
                if _item_companies:
                    _items.append(_item_companies.to_dict())
            _dict["companies"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_companies (list)
        _items = []
        if self.top_companies:
            for _item_top_companies in self.top_companies:
                if _item_top_companies:
                    _items.append(_item_top_companies.to_dict())
            _dict["topCompanies"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in locations (list)
        _items = []
        if self.locations:
            for _item_locations in self.locations:
                if _item_locations:
                    _items.append(_item_locations.to_dict())
            _dict["locations"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_locations (list)
        _items = []
        if self.top_locations:
            for _item_top_locations in self.top_locations:
                if _item_top_locations:
                    _items.append(_item_top_locations.to_dict())
            _dict["topLocations"] = _items
        # set to None if created_at (nullable) is None
        # and model_fields_set contains the field
        if self.created_at is None and "created_at" in self.model_fields_set:
            _dict["createdAt"] = None

        # set to None if updated_at (nullable) is None
        # and model_fields_set contains the field
        if self.updated_at is None and "updated_at" in self.model_fields_set:
            _dict["updatedAt"] = None

        # set to None if initialized_at (nullable) is None
        # and model_fields_set contains the field
        if self.initialized_at is None and "initialized_at" in self.model_fields_set:
            _dict["initializedAt"] = None

        # set to None if id (nullable) is None
        # and model_fields_set contains the field
        if self.id is None and "id" in self.model_fields_set:
            _dict["id"] = None

        # set to None if duplicate_of (nullable) is None
        # and model_fields_set contains the field
        if self.duplicate_of is None and "duplicate_of" in self.model_fields_set:
            _dict["duplicateOf"] = None

        # set to None if slug (nullable) is None
        # and model_fields_set contains the field
        if self.slug is None and "slug" in self.model_fields_set:
            _dict["slug"] = None

        # set to None if name (nullable) is None
        # and model_fields_set contains the field
        if self.name is None and "name" in self.model_fields_set:
            _dict["name"] = None

        # set to None if summary (nullable) is None
        # and model_fields_set contains the field
        if self.summary is None and "summary" in self.model_fields_set:
            _dict["summary"] = None

        # set to None if short_summary (nullable) is None
        # and model_fields_set contains the field
        if self.short_summary is None and "short_summary" in self.model_fields_set:
            _dict["shortSummary"] = None

        # set to None if summary_references (nullable) is None
        # and model_fields_set contains the field
        if (
            self.summary_references is None
            and "summary_references" in self.model_fields_set
        ):
            _dict["summaryReferences"] = None

        # set to None if image_source (nullable) is None
        # and model_fields_set contains the field
        if self.image_source is None and "image_source" in self.model_fields_set:
            _dict["imageSource"] = None

        # set to None if image_url (nullable) is None
        # and model_fields_set contains the field
        if self.image_url is None and "image_url" in self.model_fields_set:
            _dict["imageUrl"] = None

        # set to None if key_points (nullable) is None
        # and model_fields_set contains the field
        if self.key_points is None and "key_points" in self.model_fields_set:
            _dict["keyPoints"] = None

        # set to None if questions (nullable) is None
        # and model_fields_set contains the field
        if self.questions is None and "questions" in self.model_fields_set:
            _dict["questions"] = None

        # set to None if unique_sources (nullable) is None
        # and model_fields_set contains the field
        if self.unique_sources is None and "unique_sources" in self.model_fields_set:
            _dict["uniqueSources"] = None

        # set to None if selected_articles (nullable) is None
        # and model_fields_set contains the field
        if (
            self.selected_articles is None
            and "selected_articles" in self.model_fields_set
        ):
            _dict["selectedArticles"] = None

        # set to None if sentiment (nullable) is None
        # and model_fields_set contains the field
        if self.sentiment is None and "sentiment" in self.model_fields_set:
            _dict["sentiment"] = None

        # set to None if unique_count (nullable) is None
        # and model_fields_set contains the field
        if self.unique_count is None and "unique_count" in self.model_fields_set:
            _dict["uniqueCount"] = None

        # set to None if reprint_count (nullable) is None
        # and model_fields_set contains the field
        if self.reprint_count is None and "reprint_count" in self.model_fields_set:
            _dict["reprintCount"] = None

        # set to None if total_count (nullable) is None
        # and model_fields_set contains the field
        if self.total_count is None and "total_count" in self.model_fields_set:
            _dict["totalCount"] = None

        # set to None if countries (nullable) is None
        # and model_fields_set contains the field
        if self.countries is None and "countries" in self.model_fields_set:
            _dict["countries"] = None

        # set to None if top_countries (nullable) is None
        # and model_fields_set contains the field
        if self.top_countries is None and "top_countries" in self.model_fields_set:
            _dict["topCountries"] = None

        # set to None if topics (nullable) is None
        # and model_fields_set contains the field
        if self.topics is None and "topics" in self.model_fields_set:
            _dict["topics"] = None

        # set to None if top_topics (nullable) is None
        # and model_fields_set contains the field
        if self.top_topics is None and "top_topics" in self.model_fields_set:
            _dict["topTopics"] = None

        # set to None if categories (nullable) is None
        # and model_fields_set contains the field
        if self.categories is None and "categories" in self.model_fields_set:
            _dict["categories"] = None

        # set to None if top_categories (nullable) is None
        # and model_fields_set contains the field
        if self.top_categories is None and "top_categories" in self.model_fields_set:
            _dict["topCategories"] = None

        # set to None if taxonomies (nullable) is None
        # and model_fields_set contains the field
        if self.taxonomies is None and "taxonomies" in self.model_fields_set:
            _dict["taxonomies"] = None

        # set to None if top_taxonomies (nullable) is None
        # and model_fields_set contains the field
        if self.top_taxonomies is None and "top_taxonomies" in self.model_fields_set:
            _dict["topTaxonomies"] = None

        # set to None if people (nullable) is None
        # and model_fields_set contains the field
        if self.people is None and "people" in self.model_fields_set:
            _dict["people"] = None

        # set to None if top_people (nullable) is None
        # and model_fields_set contains the field
        if self.top_people is None and "top_people" in self.model_fields_set:
            _dict["topPeople"] = None

        # set to None if companies (nullable) is None
        # and model_fields_set contains the field
        if self.companies is None and "companies" in self.model_fields_set:
            _dict["companies"] = None

        # set to None if top_companies (nullable) is None
        # and model_fields_set contains the field
        if self.top_companies is None and "top_companies" in self.model_fields_set:
            _dict["topCompanies"] = None

        # set to None if locations (nullable) is None
        # and model_fields_set contains the field
        if self.locations is None and "locations" in self.model_fields_set:
            _dict["locations"] = None

        # set to None if top_locations (nullable) is None
        # and model_fields_set contains the field
        if self.top_locations is None and "top_locations" in self.model_fields_set:
            _dict["topLocations"] = None

        # set to None if highlights (nullable) is None
        # and model_fields_set contains the field
        if self.highlights is None and "highlights" in self.model_fields_set:
            _dict["highlights"] = None

        return _dict

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

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

        _obj = cls.model_validate(
            {
                "createdAt": obj.get("createdAt"),
                "updatedAt": obj.get("updatedAt"),
                "initializedAt": obj.get("initializedAt"),
                "id": obj.get("id"),
                "duplicateOf": obj.get("duplicateOf"),
                "slug": obj.get("slug"),
                "name": obj.get("name"),
                "summary": obj.get("summary"),
                "shortSummary": obj.get("shortSummary"),
                "summaryReferences": obj.get("summaryReferences"),
                "imageSource": (
                    SourceHolder.from_dict(obj["imageSource"])
                    if obj.get("imageSource") is not None
                    else None
                ),
                "imageUrl": obj.get("imageUrl"),
                "keyPoints": (
                    [KeyPoint.from_dict(_item) for _item in obj["keyPoints"]]
                    if obj.get("keyPoints") is not None
                    else None
                ),
                "questions": (
                    [Question.from_dict(_item) for _item in obj["questions"]]
                    if obj.get("questions") is not None
                    else None
                ),
                "uniqueSources": obj.get("uniqueSources"),
                "selectedArticles": (
                    [Article.from_dict(_item) for _item in obj["selectedArticles"]]
                    if obj.get("selectedArticles") is not None
                    else None
                ),
                "sentiment": (
                    SentimentHolder.from_dict(obj["sentiment"])
                    if obj.get("sentiment") is not None
                    else None
                ),
                "uniqueCount": obj.get("uniqueCount"),
                "reprintCount": obj.get("reprintCount"),
                "totalCount": obj.get("totalCount"),
                "countries": (
                    [RecordStatHolder.from_dict(_item) for _item in obj["countries"]]
                    if obj.get("countries") is not None
                    else None
                ),
                "topCountries": obj.get("topCountries"),
                "topics": (
                    [RecordStatHolder.from_dict(_item) for _item in obj["topics"]]
                    if obj.get("topics") is not None
                    else None
                ),
                "topTopics": (
                    [TopicHolder.from_dict(_item) for _item in obj["topTopics"]]
                    if obj.get("topTopics") is not None
                    else None
                ),
                "categories": (
                    [RecordStatHolder.from_dict(_item) for _item in obj["categories"]]
                    if obj.get("categories") is not None
                    else None
                ),
                "topCategories": (
                    [CategoryHolder.from_dict(_item) for _item in obj["topCategories"]]
                    if obj.get("topCategories") is not None
                    else None
                ),
                "taxonomies": (
                    [RecordStatHolder.from_dict(_item) for _item in obj["taxonomies"]]
                    if obj.get("taxonomies") is not None
                    else None
                ),
                "topTaxonomies": (
                    [CategoryHolder.from_dict(_item) for _item in obj["topTaxonomies"]]
                    if obj.get("topTaxonomies") is not None
                    else None
                ),
                "people": (
                    [PersonCount.from_dict(_item) for _item in obj["people"]]
                    if obj.get("people") is not None
                    else None
                ),
                "topPeople": (
                    [PersonHolder.from_dict(_item) for _item in obj["topPeople"]]
                    if obj.get("topPeople") is not None
                    else None
                ),
                "companies": (
                    [CompanyCount.from_dict(_item) for _item in obj["companies"]]
                    if obj.get("companies") is not None
                    else None
                ),
                "topCompanies": (
                    [CompanyHolder.from_dict(_item) for _item in obj["topCompanies"]]
                    if obj.get("topCompanies") is not None
                    else None
                ),
                "locations": (
                    [LocationCount.from_dict(_item) for _item in obj["locations"]]
                    if obj.get("locations") is not None
                    else None
                ),
                "topLocations": (
                    [LocationHolder.from_dict(_item) for _item in obj["topLocations"]]
                    if obj.get("topLocations") is not None
                    else None
                ),
                "highlights": obj.get("highlights"),
            }
        )
        return _obj


from perigon.models.article import Article

# TODO: Rewrite to not use raise_errors
NewsCluster.model_rebuild(raise_errors=False)
