# 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


class WikipediaSearchFilter(BaseModel):
    """
    Complex filter structure for Wikipedia page searches that supports nested logical operations (AND, OR, NOT) and multiple filtering criteria.
    """  # noqa: E501

    page_id: Optional[List[StrictStr]] = Field(
        default=None,
        description="Filter by specific Perigon page identifiers. Accepts either a single ID or an array of IDs. Returns only pages matching these IDs.",
        alias="pageId",
    )
    section_id: Optional[List[StrictStr]] = Field(
        default=None,
        description="Filter by specific section identifiers. Accepts either a single ID or an array of IDs. Returns only pages containing these sections.",
        alias="sectionId",
    )
    wiki_page_id: Optional[List[StrictInt]] = Field(
        default=None,
        description="Filter by specific Wikipedia page identifiers. Accepts either a single ID or an array of IDs. Returns only pages matching these IDs.",
        alias="wikiPageId",
    )
    wiki_revision_id: Optional[List[StrictInt]] = Field(
        default=None,
        description="Filter by specific Perigon page revision identifiers. Accepts either a single ID or an array of IDs. Returns only pages matching these IDs.",
        alias="wikiRevisionId",
    )
    wiki_code: Optional[List[StrictStr]] = Field(
        default=None,
        description="Filter by specific Wikipedia project codes. Returns only pages matching these projects.",
        alias="wikiCode",
    )
    wiki_namespace: Optional[List[StrictInt]] = Field(
        default=None,
        description="Filter by specific Wikipedia namespaces. Returns only pages matching these namespaces.",
        alias="wikiNamespace",
    )
    wikidata_id: Optional[List[StrictStr]] = Field(
        default=None,
        description="Filter by specific Wikidata entity IDs. Returns only pages whose Wikidata entities match those ids.",
        alias="wikidataId",
    )
    wikidata_instance_of_id: Optional[List[StrictStr]] = Field(
        default=None,
        description="Filter by specific Wikidata entity IDs. Returns only pages whose Wikidata entities are instances of provided ids.",
        alias="wikidataInstanceOfId",
    )
    wikidata_instance_of_label: Optional[List[StrictStr]] = Field(
        default=None,
        description="Filter by specific Wikidata entity labels. Returns only pages whose Wikidata entities are instances of these labels.",
        alias="wikidataInstanceOfLabel",
    )
    var_and: Optional[List[WikipediaSearchFilter]] = Field(
        default=None,
        description="Adds additional AND filter objects. These objects must be of the same type as the original filter object and will be combined with the existing filter using the AND logical operator.",
        alias="AND",
    )
    var_or: Optional[List[WikipediaSearchFilter]] = Field(
        default=None,
        description="Adds additional OR filter objects. These objects must be of the same type as the original filter object and will be combined with the existing filter using the OR logical operator.",
        alias="OR",
    )
    var_not: Optional[List[WikipediaSearchFilter]] = Field(
        default=None,
        description="A filter object for logical NOT operations",
        alias="NOT",
    )
    __properties: ClassVar[List[str]] = [
        "pageId",
        "sectionId",
        "wikiPageId",
        "wikiRevisionId",
        "wikiCode",
        "wikiNamespace",
        "wikidataId",
        "wikidataInstanceOfId",
        "wikidataInstanceOfLabel",
        "AND",
        "OR",
        "NOT",
    ]

    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 WikipediaSearchFilter 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 var_and (list)
        _items = []
        if self.var_and:
            for _item_var_and in self.var_and:
                if _item_var_and:
                    _items.append(_item_var_and.to_dict())
            _dict["AND"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in var_or (list)
        _items = []
        if self.var_or:
            for _item_var_or in self.var_or:
                if _item_var_or:
                    _items.append(_item_var_or.to_dict())
            _dict["OR"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in var_not (list)
        _items = []
        if self.var_not:
            for _item_var_not in self.var_not:
                if _item_var_not:
                    _items.append(_item_var_not.to_dict())
            _dict["NOT"] = _items
        # set to None if page_id (nullable) is None
        # and model_fields_set contains the field
        if self.page_id is None and "page_id" in self.model_fields_set:
            _dict["pageId"] = None

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

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

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

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

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

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

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

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

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

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

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

        return _dict

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

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

        _obj = cls.model_validate(
            {
                "pageId": obj.get("pageId"),
                "sectionId": obj.get("sectionId"),
                "wikiPageId": obj.get("wikiPageId"),
                "wikiRevisionId": obj.get("wikiRevisionId"),
                "wikiCode": obj.get("wikiCode"),
                "wikiNamespace": obj.get("wikiNamespace"),
                "wikidataId": obj.get("wikidataId"),
                "wikidataInstanceOfId": obj.get("wikidataInstanceOfId"),
                "wikidataInstanceOfLabel": obj.get("wikidataInstanceOfLabel"),
                "AND": (
                    [WikipediaSearchFilter.from_dict(_item) for _item in obj["AND"]]
                    if obj.get("AND") is not None
                    else None
                ),
                "OR": (
                    [WikipediaSearchFilter.from_dict(_item) for _item in obj["OR"]]
                    if obj.get("OR") is not None
                    else None
                ),
                "NOT": (
                    [WikipediaSearchFilter.from_dict(_item) for _item in obj["NOT"]]
                    if obj.get("NOT") is not None
                    else None
                ),
            }
        )
        return _obj


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