# generated by datamodel-codegen:
#   filename:  Event.json

from __future__ import annotations

from enum import Enum
from typing import Literal, Optional

from pydantic import BaseModel, ConfigDict, Field, constr


class Metadata(BaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    name: constr(pattern=r'^[a-z0-9]+(?:\.[a-z0-9]+)*$') = Field(
        ...,
        description="Event routing key in lowercase dot-notation (e.g., 'video.uploaded', 'user.created'). This is used for event matching and routing.",
    )
    intent: str = Field(
        ...,
        description="Human-readable description of when and why this event occurs (e.g., 'Triggered when a user uploads a video file')",
    )
    tags: Optional[list[str]] = Field(
        None,
        description="Categorization tags for organization and filtering (e.g., ['video', 'upload', 'media'])",
    )


class Strategy(Enum):
    none = 'none'
    key = 'key'
    round_robin = 'round-robin'


class Partitioning(BaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    strategy: Optional[Strategy] = Field(
        None,
        description="Partitioning strategy: 'none' = single partition, 'key' = partition by field, 'round-robin' = distribute evenly",
    )
    key: Optional[str] = Field(
        None, description="Field to use for key-based partitioning (e.g., 'user_id', 'tenant_id')"
    )


class Compatibility(Enum):
    backward = 'backward'
    forward = 'forward'
    full = 'full'
    none = 'none'


class Contract(BaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: str = Field(
        ...,
        description="Relative path to the data-type manifest describing the payload (e.g., './types/VideoUploadedEvent.yml').",
    )
    retention: Optional[str] = Field(
        None,
        description="How long to retain event in the Redis stream (e.g., '7d', '24h'). Parsed into seconds during provisioning.",
    )
    partitioning: Optional[Partitioning] = Field(
        None, description='Stream partitioning strategy for scalability'
    )
    compatibility: Optional[Compatibility] = Field(
        None,
        description="Schema evolution compatibility: 'backward' = new consumers read old events, 'forward' = old consumers read new events, 'full' = both, 'none' = breaking changes allowed",
    )
    producers: Optional[list[str]] = Field(
        None,
        description='Processes or components expected to publish the event (use snapshot-relative paths when possible).',
    )


class Event(BaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['Event']
    schema_version: str = Field(..., description="DSL version (e.g., 'v2')")
    metadata: Metadata
    contract: Contract = Field(
        ...,
        description='Event contract defines the structure, retention, and compatibility of the event payload',
    )
