# 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, StrictBool, StrictInt, StrictStr
from typing_extensions import Self

from perigon.models.image_holder import ImageHolder
from perigon.models.source_location import SourceLocation
from perigon.models.source_top_stat_holder import SourceTopStatHolder


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

    id: Optional[StrictStr] = None
    domain: Optional[StrictStr] = None
    name: Optional[StrictStr] = None
    primary_record_id: Optional[StrictStr] = Field(
        default=None, alias="primaryRecordId"
    )
    updated_at: Optional[StrictStr] = Field(default=None, alias="updatedAt")
    alt_names: Optional[List[StrictStr]] = Field(default=None, alias="altNames")
    description: Optional[StrictStr] = None
    avg_monthly_posts: Optional[StrictInt] = Field(
        default=None, alias="avgMonthlyPosts"
    )
    paywall: Optional[StrictBool] = None
    location: Optional[SourceLocation] = None
    top_categories: Optional[List[SourceTopStatHolder]] = Field(
        default=None, alias="topCategories"
    )
    top_topics: Optional[List[SourceTopStatHolder]] = Field(
        default=None, alias="topTopics"
    )
    top_countries: Optional[List[SourceTopStatHolder]] = Field(
        default=None, alias="topCountries"
    )
    top_labels: Optional[List[SourceTopStatHolder]] = Field(
        default=None, alias="topLabels"
    )
    avg_bias_rating: Optional[StrictStr] = Field(default=None, alias="avgBiasRating")
    ad_fontes_bias_rating: Optional[StrictStr] = Field(
        default=None, alias="adFontesBiasRating"
    )
    all_sides_bias_rating: Optional[StrictStr] = Field(
        default=None, alias="allSidesBiasRating"
    )
    mbfc_bias_rating: Optional[StrictStr] = Field(default=None, alias="mbfcBiasRating")
    monthly_visits: Optional[StrictInt] = Field(default=None, alias="monthlyVisits")
    global_rank: Optional[StrictInt] = Field(default=None, alias="globalRank")
    logo_large: Optional[ImageHolder] = Field(default=None, alias="logoLarge")
    logo_fav_icon: Optional[ImageHolder] = Field(default=None, alias="logoFavIcon")
    logo_square: Optional[ImageHolder] = Field(default=None, alias="logoSquare")
    __properties: ClassVar[List[str]] = [
        "id",
        "domain",
        "name",
        "primaryRecordId",
        "updatedAt",
        "altNames",
        "description",
        "avgMonthlyPosts",
        "paywall",
        "location",
        "topCategories",
        "topTopics",
        "topCountries",
        "topLabels",
        "avgBiasRating",
        "adFontesBiasRating",
        "allSidesBiasRating",
        "mbfcBiasRating",
        "monthlyVisits",
        "globalRank",
        "logoLarge",
        "logoFavIcon",
        "logoSquare",
    ]

    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 Source 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 location
        if self.location:
            _dict["location"] = self.location.to_dict()
        # 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 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 top_countries (list)
        _items = []
        if self.top_countries:
            for _item_top_countries in self.top_countries:
                if _item_top_countries:
                    _items.append(_item_top_countries.to_dict())
            _dict["topCountries"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_labels (list)
        _items = []
        if self.top_labels:
            for _item_top_labels in self.top_labels:
                if _item_top_labels:
                    _items.append(_item_top_labels.to_dict())
            _dict["topLabels"] = _items
        # override the default output from pydantic by calling `to_dict()` of logo_large
        if self.logo_large:
            _dict["logoLarge"] = self.logo_large.to_dict()
        # override the default output from pydantic by calling `to_dict()` of logo_fav_icon
        if self.logo_fav_icon:
            _dict["logoFavIcon"] = self.logo_fav_icon.to_dict()
        # override the default output from pydantic by calling `to_dict()` of logo_square
        if self.logo_square:
            _dict["logoSquare"] = self.logo_square.to_dict()
        # 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 domain (nullable) is None
        # and model_fields_set contains the field
        if self.domain is None and "domain" in self.model_fields_set:
            _dict["domain"] = 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 primary_record_id (nullable) is None
        # and model_fields_set contains the field
        if (
            self.primary_record_id is None
            and "primary_record_id" in self.model_fields_set
        ):
            _dict["primaryRecordId"] = 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 alt_names (nullable) is None
        # and model_fields_set contains the field
        if self.alt_names is None and "alt_names" in self.model_fields_set:
            _dict["altNames"] = None

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

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

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

        # set to None if location (nullable) is None
        # and model_fields_set contains the field
        if self.location is None and "location" in self.model_fields_set:
            _dict["location"] = 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 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 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 top_labels (nullable) is None
        # and model_fields_set contains the field
        if self.top_labels is None and "top_labels" in self.model_fields_set:
            _dict["topLabels"] = None

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

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

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

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

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

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

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

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

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

        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of Source 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"),
                "domain": obj.get("domain"),
                "name": obj.get("name"),
                "primaryRecordId": obj.get("primaryRecordId"),
                "updatedAt": obj.get("updatedAt"),
                "altNames": obj.get("altNames"),
                "description": obj.get("description"),
                "avgMonthlyPosts": obj.get("avgMonthlyPosts"),
                "paywall": obj.get("paywall"),
                "location": (
                    SourceLocation.from_dict(obj["location"])
                    if obj.get("location") is not None
                    else None
                ),
                "topCategories": (
                    [
                        SourceTopStatHolder.from_dict(_item)
                        for _item in obj["topCategories"]
                    ]
                    if obj.get("topCategories") is not None
                    else None
                ),
                "topTopics": (
                    [SourceTopStatHolder.from_dict(_item) for _item in obj["topTopics"]]
                    if obj.get("topTopics") is not None
                    else None
                ),
                "topCountries": (
                    [
                        SourceTopStatHolder.from_dict(_item)
                        for _item in obj["topCountries"]
                    ]
                    if obj.get("topCountries") is not None
                    else None
                ),
                "topLabels": (
                    [SourceTopStatHolder.from_dict(_item) for _item in obj["topLabels"]]
                    if obj.get("topLabels") is not None
                    else None
                ),
                "avgBiasRating": obj.get("avgBiasRating"),
                "adFontesBiasRating": obj.get("adFontesBiasRating"),
                "allSidesBiasRating": obj.get("allSidesBiasRating"),
                "mbfcBiasRating": obj.get("mbfcBiasRating"),
                "monthlyVisits": obj.get("monthlyVisits"),
                "globalRank": obj.get("globalRank"),
                "logoLarge": (
                    ImageHolder.from_dict(obj["logoLarge"])
                    if obj.get("logoLarge") is not None
                    else None
                ),
                "logoFavIcon": (
                    ImageHolder.from_dict(obj["logoFavIcon"])
                    if obj.get("logoFavIcon") is not None
                    else None
                ),
                "logoSquare": (
                    ImageHolder.from_dict(obj["logoSquare"])
                    if obj.get("logoSquare") is not None
                    else None
                ),
            }
        )
        return _obj
