from __future__ import annotations

from typing import Any, Optional, Union, Literal
from datetime import datetime

from pydantic.main import BaseConfig, BaseModel

from webhook.utils import WrappedBaseModel


def to_camel(string: str) -> str:
    first, *rest = string.split("_")
    return first + "".join(word.capitalize() for word in rest)


class CamelcaseBaseModel(BaseModel):
    class Config(BaseConfig):
        alias_generator = to_camel
        allow_population_by_field_name = True


class DialogflowIntent(CamelcaseBaseModel):
    name: str
    display_name: str


class DialogflowQueryResult(CamelcaseBaseModel):
    query_text: str
    language_code: str
    action: str

    parameters: dict[str, Any]
    all_required_params_present: bool
    fulfillment_messages: Optional[list[dict[str, Any]]]

    intent: DialogflowIntent


class DialogflowSource(CamelcaseBaseModel):
    source: str
    payload: Optional[dict]


class DialogflowRequest(CamelcaseBaseModel):
    response_id: str
    session: str
    original_detect_intent_request: Optional[DialogflowSource]
    query_result: DialogflowQueryResult


class ForwardParams(BaseModel):
    start: str
    end: str
    path: list[str]


class DialogflowMessageText(WrappedBaseModel("text", CamelcaseBaseModel)):
    text: list[str]


DialogflowMessage = Union[DialogflowMessageText]


class DialogflowResponse(CamelcaseBaseModel):
    fulfillment_messages: Optional[list[DialogflowMessage]]


class AlertLabels(BaseModel):
    alertname: str
    service: str

    class Config(BaseConfig):
        extra = "allow"


class DroppingPacketsLabels(AlertLabels):
    alertname: Literal["DetectDroppingPackets"]
    device: str
    port: int


class AlertmanagerAlert(CamelcaseBaseModel):
    status: str
    labels: Union[DroppingPacketsLabels, AlertLabels]
    annotations: dict[str, str]
    starts_at: datetime
    ends_at: datetime
    fingerprint: str

    def display_pretty(self):
        match self.labels:
            case DroppingPacketsLabels():
                return self.render_packet_drop(self.labels)
        return self.render_generic()

    def render_packet_drop(self, labels: DroppingPacketsLabels):
        return f"Device {labels.device} is dropping packets on port {labels.port}"

    def render_generic(self):
        return f"Alert {self.labels.alertname} is firing: {self.labels}"


class AlertmanagerMessage(CamelcaseBaseModel):
    receiver: str
    status: str
    alerts: list[AlertmanagerAlert]

from __future__ import annotations

from typing import Any, Optional, Union, Literal
from datetime import datetime

from pydantic.main import BaseConfig, BaseModel

from webhook.utils import WrappedBaseModel


def to_camel(string: str) -> str:
    first, *rest = string.split("_")
    return first + "".join(word.capitalize() for word in rest)


class CamelcaseBaseModel(BaseModel):
    class Config(BaseConfig):
        alias_generator = to_camel
        allow_population_by_field_name = True


class DialogflowIntent(CamelcaseBaseModel):
    name: str
    display_name: str


class DialogflowQueryResult(CamelcaseBaseModel):
    query_text: str
    language_code: str
    action: str

    parameters: dict[str, Any]
    all_required_params_present: bool
    fulfillment_messages: Optional[list[dict[str, Any]]]

    intent: DialogflowIntent


class DialogflowSource(CamelcaseBaseModel):
    source: str
    payload: Optional[dict]


class DialogflowRequest(CamelcaseBaseModel):
    response_id: str
    session: str
    original_detect_intent_request: Optional[DialogflowSource]
    query_result: DialogflowQueryResult


class ForwardParams(BaseModel):
    start: str
    end: str
    path: list[str]


class DialogflowMessageText(WrappedBaseModel("text", CamelcaseBaseModel)):
    text: list[str]


DialogflowMessage = Union[DialogflowMessageText]


class DialogflowResponse(CamelcaseBaseModel):
    fulfillment_messages: Optional[list[DialogflowMessage]]


class AlertLabels(BaseModel):
    alertname: str
    service: str

    class Config(BaseConfig):
        extra = "allow"


class DroppingPacketsLabels(AlertLabels):
    alertname: Literal["DetectDroppingPackets"]
    device: str
    port: int


class AlertmanagerAlert(CamelcaseBaseModel):
    status: str
    labels: Union[DroppingPacketsLabels, AlertLabels]
    annotations: dict[str, str]
    starts_at: datetime
    ends_at: datetime
    fingerprint: str

    def display_pretty(self):
        match self.labels:
            case DroppingPacketsLabels():
                return self.render_packet_drop(self.labels)
        return self.render_generic()

    def render_packet_drop(self, labels: DroppingPacketsLabels):
        return f"Device {labels.device} is dropping packets on port {labels.port}"

    def render_generic(self):
        return f"Alert {self.labels.alertname} is firing: {self.labels}"


class AlertmanagerMessage(CamelcaseBaseModel):
    receiver: str
    status: str
    alerts: list[AlertmanagerAlert]
