from __future__ import annotations

from typing import Any, Optional

from pydantic import BaseModel, ConfigDict, Field, model_validator

from goodmem.models.ping_result import PingResult
from goodmem.models.ping_summary import PingSummary
from goodmem.models.ping_notice import PingNotice


class PingEvent(BaseModel):
    """Streaming event from a ping session"""

    model_config = ConfigDict(populate_by_name=True, protected_namespaces=())

    result: Optional[PingResult] = Field(default=None, description='Probe result event')
    summary: Optional[PingSummary] = Field(default=None, description='Summary emitted at session completion')
    notice: Optional[PingNotice] = Field(default=None, description='Non-fatal notice emitted during session')

    @model_validator(mode='after')
    def _check_exactly_one_variant(self) -> 'PingEvent':
        _variant_fields = ['result', 'summary', 'notice']
        _set = [f for f in _variant_fields if getattr(self, f) is not None]
        if len(_set) != 1:
            raise ValueError(
                f"Exactly one of result, summary, notice must be set, "
                f"got {len(_set)}: {_set or 'none'}"
            )
        return self

