# coding: utf-8

"""
    Pinterest REST API

    Pinterest's REST API

    The version of the OpenAPI document: 5.23.0
    Contact: blah+oapicf@cliffano.com
    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, StrictInt, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional
from typing_extensions import Annotated
from pinterestsdk.models.event_data import EventData
from pinterestsdk.models.objective_type import ObjectiveType
from typing import Optional, Set
from typing_extensions import Self

class AudienceRule(BaseModel):
    """
    JSON object defining targeted audience users. Example rule formats per audience type:<br>CUSTOMER_LIST: { \"customer_list_id\": \"&lt;customer list ID&gt;\"}<br>ACTALIKE: { \"seed_id\": [\"&lt;audience ID&gt;\"], \"country\": \"US\", \"percentage\": \"10\" }<br>(Valid countries include: \"US\", \"CA\", and \"GB\". Percentage should be 1-10.<br>The targeted audience should be this % size across Pinterest.)<br>VISITOR: { \"visitor_source_id\": [\"&lt;conversion tag ID&gt;\"], \"retention_days\": \"180\", \"event_source\": {\"=\": [\"web\", \"mobile\"]}, \"ingestion_source\": {\"=\": [\"tag\"]}}<br>(Retention days should be 1-540. Retention applies to specific customers.)<br>ENGAGEMENT: {\"engagement_domain\": [\"www.example.com\"], \"engager_type\": 1}<br>Learn more about <a href=\"/docs/work-with-targets-and-audiences/create-audiences/#engagement-audience\" target=\"_blank\">engagement audiences</a>.
    """ # noqa: E501
    ad_account_id: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="Ad account ID.")
    ad_id: Optional[List[Annotated[str, Field(strict=True)]]] = Field(default=None, description="Ad ID for engagement audience filter.")
    campaign_id: Optional[List[Annotated[str, Field(strict=True)]]] = Field(default=None, description="Campaign ID for engagement audience filter.")
    country: Optional[StrictStr] = Field(default=None, description="Valid countries include: \"US\", \"CA\", and \"GB\".")
    customer_list_id: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="Customer list ID. For CUSTOMER_LIST `audience_type`.")
    engagement_domain: Optional[List[StrictStr]] = Field(default=None, description="The audience account's verified domain. **Required** for ENGAGEMENT `audience_type`.")
    engagement_type: Optional[StrictStr] = Field(default=None, description="Engagement type enum. Optional for ENGAGEMENT `audience_type`. Supported values are `click`, `save`, `closeup`, `comment` and `like`. All engagements are included if this field is not set. ")
    engager_type: Optional[StrictInt] = Field(default=None, description="Optional for ENGAGEMENT. Engager type value should be 1-2.")
    event: Optional[StrictStr] = Field(default=None, description="A Pinterest tag event. Optional for VISITOR `audience_type`. Possible values are `pagevisit`, `signup`, `checkout`, `viewcategory`, `search`, `addtocart`, `watchvideo`, `lead`, and `custom`. This field also accepts a partner-defined Pinterest tag event.")
    event_data: Optional[EventData] = None
    event_source: Optional[Dict[str, Any]] = Field(default=None, description="Optional for VISITOR. You can use it as a {'=': [value]}. Supported values are: web, mobile, offline")
    ingestion_source: Optional[Dict[str, Any]] = Field(default=None, description="Optional for VISITOR. You can use it as a {'=': [value]}. Supported values are: tag, mmp, file_upload, conversions_api")
    objective_type: Optional[List[ObjectiveType]] = Field(default=None, description="Objective for engagement audience filter.")
    percentage: Optional[StrictInt] = Field(default=None, description="Percentage should be 1-10. The targeted audience should be this % size across Pinterest.")
    pin_id: Optional[List[Annotated[str, Field(strict=True)]]] = Field(default=None, description="IDs of engaged organic pins. Optional for ENGAGEMENT `audience_type`. For example, \"pin_id:\": [\"34567\"]")
    prefill: Optional[StrictBool] = Field(default=None, description="Optional for VISITOR `audience_type`. If `true`, the specified rule on existing engagement data is applied to pre-populate the audience. If `false`, the audience is empty at creation time. The default is `true`.")
    retention_days: Optional[StrictInt] = Field(default=None, description="Number of days a Pinterest user remains in the audience. Optional for ENGAGEMENT and VISITOR `audience_type`. Accepted range is 1-540. Defaults to 180 if not specified.")
    seed_id: Optional[List[Annotated[str, Field(strict=True)]]] = Field(default=None, description="Audience ID(s). For ACTALIKE `audience_type`. ")
    url: Optional[List[StrictStr]] = Field(default=None, description="Optional for ENGAGEMENT or VISITOR `audience_type`. For ENGAGEMENT, it is the engaged pin's URL. For VISITOR, you can use it as a string or a {operator: value} object for filtering visitors based on conversion tag event URLs. Supported operators are [ =, !=, contains, not_contains].<br>Example 1:  \"url\": \"http://www.myonlinestore123.com/view_item/shoe\"<br>Example 2: \"url\": {\"contains\": \"/view_item/shoe\"}")
    visitor_source_id: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="The conversion tag ID, or the Pinterest tag ID, that you use on your website. For VISITOR `audience_type`.")
    __properties: ClassVar[List[str]] = ["ad_account_id", "ad_id", "campaign_id", "country", "customer_list_id", "engagement_domain", "engagement_type", "engager_type", "event", "event_data", "event_source", "ingestion_source", "objective_type", "percentage", "pin_id", "prefill", "retention_days", "seed_id", "url", "visitor_source_id"]

    @field_validator('ad_account_id')
    def ad_account_id_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^\d+$", value):
            raise ValueError(r"must validate the regular expression /^\d+$/")
        return value

    @field_validator('customer_list_id')
    def customer_list_id_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^\d+$", value):
            raise ValueError(r"must validate the regular expression /^\d+$/")
        return value

    @field_validator('visitor_source_id')
    def visitor_source_id_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^\d+$", value):
            raise ValueError(r"must validate the regular expression /^\d+$/")
        return value

    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 AudienceRule 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 event_data
        if self.event_data:
            _dict['event_data'] = self.event_data.to_dict()
        return _dict

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

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

        _obj = cls.model_validate({
            "ad_account_id": obj.get("ad_account_id"),
            "ad_id": obj.get("ad_id"),
            "campaign_id": obj.get("campaign_id"),
            "country": obj.get("country"),
            "customer_list_id": obj.get("customer_list_id"),
            "engagement_domain": obj.get("engagement_domain"),
            "engagement_type": obj.get("engagement_type"),
            "engager_type": obj.get("engager_type"),
            "event": obj.get("event"),
            "event_data": EventData.from_dict(obj["event_data"]) if obj.get("event_data") is not None else None,
            "event_source": obj.get("event_source"),
            "ingestion_source": obj.get("ingestion_source"),
            "objective_type": obj.get("objective_type"),
            "percentage": obj.get("percentage"),
            "pin_id": obj.get("pin_id"),
            "prefill": obj.get("prefill"),
            "retention_days": obj.get("retention_days"),
            "seed_id": obj.get("seed_id"),
            "url": obj.get("url"),
            "visitor_source_id": obj.get("visitor_source_id")
        })
        return _obj


