# generated by datamodel-codegen:
#   filename:  core/frequency_cap.json
#   timestamp: 2026-02-28T17:39:50+00:00

from __future__ import annotations

from typing import Annotated

from adcp.types.base import AdCPBaseModel
from pydantic import ConfigDict, Field, RootModel

from ..enums import reach_unit
from . import duration


class FrequencyCap1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    max_impressions: Annotated[
        int | None,
        Field(
            description="Maximum number of impressions per entity per window. For duration windows, implementations typically use a rolling window; 'campaign' applies a fixed cap across the full flight.",
            ge=1,
        ),
    ] = None
    per: Annotated[
        reach_unit.ReachUnit | None,
        Field(
            description='Entity granularity for impression counting. Required when max_impressions is set.'
        ),
    ] = None
    suppress: Annotated[
        duration.Duration,
        Field(
            description='Cooldown period between consecutive exposures to the same entity. Prevents back-to-back ad delivery (e.g. {"interval": 60, "unit": "minutes"} for a 1-hour cooldown). Preferred over suppress_minutes.'
        ),
    ]
    suppress_minutes: Annotated[
        float | None,
        Field(
            description='Deprecated — use suppress instead. Cooldown period in minutes between consecutive exposures to the same entity (e.g. 60 for a 1-hour cooldown).',
            ge=0.0,
        ),
    ] = None
    window: Annotated[
        duration.Duration | None,
        Field(
            description='Time window for the max_impressions cap (e.g. {"interval": 7, "unit": "days"} or {"interval": 1, "unit": "campaign"} for the full flight). Required when max_impressions is set.'
        ),
    ] = None


class FrequencyCap2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    max_impressions: Annotated[
        int | None,
        Field(
            description="Maximum number of impressions per entity per window. For duration windows, implementations typically use a rolling window; 'campaign' applies a fixed cap across the full flight.",
            ge=1,
        ),
    ] = None
    per: Annotated[
        reach_unit.ReachUnit | None,
        Field(
            description='Entity granularity for impression counting. Required when max_impressions is set.'
        ),
    ] = None
    suppress: Annotated[
        duration.Duration | None,
        Field(
            description='Cooldown period between consecutive exposures to the same entity. Prevents back-to-back ad delivery (e.g. {"interval": 60, "unit": "minutes"} for a 1-hour cooldown). Preferred over suppress_minutes.'
        ),
    ] = None
    suppress_minutes: Annotated[
        float,
        Field(
            description='Deprecated — use suppress instead. Cooldown period in minutes between consecutive exposures to the same entity (e.g. 60 for a 1-hour cooldown).',
            ge=0.0,
        ),
    ]
    window: Annotated[
        duration.Duration | None,
        Field(
            description='Time window for the max_impressions cap (e.g. {"interval": 7, "unit": "days"} or {"interval": 1, "unit": "campaign"} for the full flight). Required when max_impressions is set.'
        ),
    ] = None


class FrequencyCap3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    max_impressions: Annotated[
        int,
        Field(
            description="Maximum number of impressions per entity per window. For duration windows, implementations typically use a rolling window; 'campaign' applies a fixed cap across the full flight.",
            ge=1,
        ),
    ]
    per: Annotated[
        reach_unit.ReachUnit | None,
        Field(
            description='Entity granularity for impression counting. Required when max_impressions is set.'
        ),
    ] = None
    suppress: Annotated[
        duration.Duration | None,
        Field(
            description='Cooldown period between consecutive exposures to the same entity. Prevents back-to-back ad delivery (e.g. {"interval": 60, "unit": "minutes"} for a 1-hour cooldown). Preferred over suppress_minutes.'
        ),
    ] = None
    suppress_minutes: Annotated[
        float | None,
        Field(
            description='Deprecated — use suppress instead. Cooldown period in minutes between consecutive exposures to the same entity (e.g. 60 for a 1-hour cooldown).',
            ge=0.0,
        ),
    ] = None
    window: Annotated[
        duration.Duration | None,
        Field(
            description='Time window for the max_impressions cap (e.g. {"interval": 7, "unit": "days"} or {"interval": 1, "unit": "campaign"} for the full flight). Required when max_impressions is set.'
        ),
    ] = None


class FrequencyCap(RootModel[FrequencyCap1 | FrequencyCap2 | FrequencyCap3]):
    root: Annotated[
        FrequencyCap1 | FrequencyCap2 | FrequencyCap3,
        Field(
            description='Frequency capping settings for package-level application. Two types of frequency control can be used independently or together: suppress enforces a cooldown between consecutive exposures; max_impressions + per + window caps total exposures per entity in a time window. When both suppress and max_impressions are set, an impression is delivered only if both constraints permit it (AND semantics). At least one of suppress, suppress_minutes, or max_impressions must be set.',
            title='Frequency Cap',
        ),
    ]
