U
    hI                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	 ddl
mZmZmZ ddlmZmZmZmZmZmZ ddlZG d	d
 d
eeZG dd deeZG dd deeeZG dd deeZdS )a  
Notification Models for Stream Processor Application

This module contains Django models for managing notifications,
including Telegram messages, email alerts, and other notification
channels. These models track notification history, delivery status,
and configuration settings.
    )models)User)timezone)MinValueValidatorMaxValueValidator)TimestampedModel	UUIDModelStatusModel)validate_name_formatvalidate_json_configurationvalidate_webhook_configvalidate_email_configvalidate_telegram_configvalidate_template_contentNc                   @   s   e Zd ZdZejddegddZdddd	d
dgZejdeddZ	ej
ddddZejeddZejdededgddZejdededgddZejdededgddZejeejdd d!ZG d"d# d#Zd$d% Zd&d' Zd(d) Zd*d+ Zd,S )-NotificationChannelaI  
    Model representing a notification delivery channel.
    
    Notification channels define how and where notifications should be sent,
    including configuration for different service types like Telegram,
    email, webhooks, and other messaging platforms.
    
    Attributes:
        name (CharField): Human-readable name for the channel
        channel_type (CharField): Type of notification channel
        is_active (BooleanField): Whether the channel is currently active
        configuration (JSONField): Channel-specific configuration data
        rate_limit (PositiveIntegerField): Maximum messages per minute
        retry_attempts (PositiveIntegerField): Number of retry attempts
        timeout_seconds (PositiveIntegerField): Timeout for delivery attempts
        created_by (ForeignKey): User who created this channel
    d   Tz0Human-readable name for the notification channel)
max_lengthunique
validators	help_text)telegramzTelegram Bot)emailZEmail)webhookZWebhook)ZslackZSlack)ZdiscordZDiscord)ZsmsZSMS   zType of notification channelr   choicesr   z+Whether this notification channel is activedefaultdb_indexr   z)Channel-specific configuration parametersr   r         i  z%Maximum number of messages per minuter   r   r      r   
   z.Number of retry attempts for failed deliveries   i,  z(Timeout for delivery attempts in secondsZnotification_channelsz*User who created this notification channel	on_deleterelated_namer   c                   @   s6   e Zd ZdZdZdgZejdgdejdgdgZdS )zNotificationChannel.MetazNotification ChannelzNotification Channelsnamechannel_typefields	is_activeN	__name__
__module____qualname__verbose_nameverbose_name_pluralorderingr   Indexindexes r7   r7   >/var/www/html/StreamProcessor/src/apps/notifications/models.pyMetai   s   r9   c                 C   s   | j  d| j dS )z2String representation of the notification channel. ())r)   r*   selfr7   r7   r8   __str__r   s    zNotificationChannel.__str__c                 C   s,   | j dkr(| jdd| jdddS i S )z$Get Telegram-specific configuration.r   	bot_token chat_id)r?   rA   r*   configurationgetr<   r7   r7   r8   get_telegram_configv   s
    
z'NotificationChannel.get_telegram_configc                 C   s,   | j dkr(| jdg | jdddS i S )z!Get email-specific configuration.r   
recipientssubject_prefixz[Stream Processor])rF   rG   rB   r<   r7   r7   r8   get_email_config   s
    
z$NotificationChannel.get_email_configc                 C   s8   | j dkr4| jdd| jdi | jdddS i S )z#Get webhook-specific configuration.r   urlr@   headersmethodPOST)rI   rJ   rK   rB   r<   r7   r7   r8   get_webhook_config   s    
z&NotificationChannel.get_webhook_configN)r/   r0   r1   __doc__r   	CharFieldr
   r)   ZCHANNEL_TYPESr*   BooleanFieldr-   	JSONFielddictrC   PositiveIntegerFieldr   r   
rate_limitretry_attemptsZtimeout_seconds
ForeignKeyr   CASCADE
created_byr9   r>   rE   rH   rM   r7   r7   r7   r8   r      sl   					r   c                   @   s   e Zd ZdZejddddZdddd	d
dddgZejdeddZejddddZ	ej
ddZejddddZejeddZejeddZG dd dZdd Zdd  Zd!d" Zd#S )$NotificationTemplatea  
    Model for notification message templates.
    
    Templates define reusable message formats for different types
    of notifications, allowing for consistent messaging and easy
    customization of notification content.
    
    Attributes:
        name (CharField): Name for the template
        template_type (CharField): Type of notification this template is for
        subject_template (CharField): Subject line template (for email)
        message_template (TextField): Main message content template
        is_active (BooleanField): Whether the template is active
        variables (JSONField): Available template variables
        channel_types (JSONField): Compatible channel types
    r   Tz#Name for this notification templater   r   r   Zjingle_detectedzJingle DetectedZad_break_startedzAd Break StartedZad_break_endedzAd Break EndedZstream_startedzStream StartedZstream_stoppedzStream StoppedZstream_errorzStream Error)Zsystem_alertzSystem Alert)Zhealth_checkzHealth Checkr    z2Type of notification this template is designed forr      z4Subject line template (used for email notifications)r   blankr   z8Main message content template with variable placeholdersr   z'Whether this template is active for user   z-List of available variables for this templater   z-List of compatible notification channel typesc                   @   s8   e Zd ZdZdZddgZejdgdejdgdgZdS )zNotificationTemplate.MetazNotification TemplatezNotification Templatestemplate_typer)   r+   r-   Nr.   r7   r7   r7   r8   r9      s   r9   c                 C   s   | j  d| j dS )z3String representation of the notification template.r:   r;   )r)   re   r<   r7   r7   r8   r>      s    zNotificationTemplate.__str__c              
   C   sF   z| j jf |W S  tk
r@ } zd|  W Y S d}~X Y nX dS )z
        Render the message template with provided context variables.
        
        Args:
            context (dict): Variables to substitute in the template
            
        Returns:
            str: Rendered message content
        z!Template error: Missing variable N)message_templateformatKeyErrorr=   contexter7   r7   r8   render_message   s    
z#NotificationTemplate.render_messagec              
   C   sZ   | j sd| j dS z| j jf |W S  tk
rT } zd|  W Y S d}~X Y nX dS )z
        Render the subject template with provided context variables.
        
        Args:
            context (dict): Variables to substitute in the template
            
        Returns:
            str: Rendered subject line
        [z] Notificationz Subject error: Missing variable N)subject_templatere   rg   rh   ri   r7   r7   r8   render_subject   s    
z#NotificationTemplate.render_subjectN)r/   r0   r1   rN   r   rO   r)   ZTEMPLATE_TYPESre   rn   	TextFieldrf   rP   r-   rQ   list	variablesZchannel_typesr9   r>   rl   ro   r7   r7   r7   r8   rY      sZ   	rY   c                   @   s
  e Zd ZdZejeejdddZeje	ej
dddddZejdd	d
ZejddddZejddZejedddZejejddZejddddZejdddZejdddZejddddZG dd dZdd Zdd  Zd!d" Z d#d$ Z!d,d&d'Z"d(d) Z#d*d+ Z$d%S )-Notificationa  
    Model representing an individual notification instance.
    
    This model tracks individual notification messages that have been
    sent or are pending delivery, including their content, delivery
    status, and any error information.
    
    Attributes:
        channel (ForeignKey): Notification channel to use for delivery
        template (ForeignKey): Template used for this notification
        recipient (CharField): Target recipient identifier
        subject (CharField): Notification subject line
        message (TextField): Notification message content
        context_data (JSONField): Variables used for template rendering
        scheduled_at (DateTimeField): When the notification should be sent
        sent_at (DateTimeField): When the notification was actually sent
        delivery_attempts (PositiveIntegerField): Number of delivery attempts
        error_message (TextField): Last error message if delivery failed
        external_id (CharField): External service message ID
    notificationsz(Notification channel to use for deliveryr&   Tz+Template used to generate this notification)r'   nullrc   r(   r   ra   z2Target recipient identifier (email, chat ID, etc.))r   r   zNotification subject linerb   zNotification message contentrd   z%Variables used for template rendering)r   rc   r   z%When this notification should be sentr   z(When this notification was actually sentru   rc   r   r   z Number of delivery attempts madez%Last error message if delivery failed)rc   r   r   z(External service message ID for trackingc                   @   sP   e Zd ZdZdZdgZejddgdejdgdejdgdejdgdgZd	S )
zNotification.Metars   Notificationsz-scheduled_atchannelstatusr+   scheduled_atsent_atNr.   r7   r7   r7   r8   r9   c  s   r9   c                 C   s"   | j j d| jp| jdd  S )z*String representation of the notification.z - N2   )rx   r)   subjectmessager<   r7   r7   r8   r>   n  s    zNotification.__str__c                 C   s   | j dko| j S )z.Check if the notification is pending delivery.pendingry   r{   r<   r7   r7   r8   
is_pendingr  s    zNotification.is_pendingc                 C   s   | j dko| jdk	S )z5Check if the notification has been successfully sent.	completedNr   r<   r7   r7   r8   is_sentv  s    zNotification.is_sentc                 C   s
   | j dkS )z.Check if the notification delivery has failed.failed)ry   r<   r7   r7   r8   	is_failedz  s    zNotification.is_failedNc                 C   s0   d| _ t | _|r|| _| jdddgd dS )z+Mark the notification as successfully sent.r   ry   r{   external_idupdate_fieldsN)ry   r   nowr{   r   save)r=   r   r7   r7   r8   	mark_sent~  s
    
zNotification.mark_sentc                 C   s0   d| _ || _|  jd7  _| jdddgd dS )z3Mark the notification as failed with error message.r   r!   ry   error_messagedelivery_attemptsr   N)ry   r   r   r   )r=   r   r7   r7   r8   mark_failed  s    zNotification.mark_failedc                 C   s   | j dko| j| jjk S )z)Check if the notification can be retried.r   )ry   r   rx   rU   r<   r7   r7   r8   	can_retry  s    
zNotification.can_retry)N)%r/   r0   r1   rN   r   rV   r   rW   rx   rY   SET_NULLtemplaterO   	recipientr}   rp   r~   rQ   rR   context_dataDateTimeFieldr   r   rz   r{   rS   r   r   r   r9   r>   r   r   r   r   r   r   r7   r7   r7   r8   rs   	  s|   

rs   c                	   @   s   e Zd ZdZejddddZdddd	d
ddddg	ZejdeddZej	e
ejdddZej	eejdddZejddddZejeddZejdededgddZejdddd Zejdd!dZG d"d# d#Zd$d% Zd&d' Zd(d) Zd*d+ Z d,S )-NotificationRulear  
    Model for automatic notification rules.
    
    Rules define when and how notifications should be automatically
    triggered based on system events, allowing for automated alerting
    and monitoring without manual intervention.
    
    Attributes:
        name (CharField): Name for the notification rule
        event_type (CharField): Type of event that triggers this rule
        channel (ForeignKey): Default channel for notifications
        template (ForeignKey): Default template for notifications
        is_active (BooleanField): Whether the rule is currently active
        conditions (JSONField): Conditions that must be met for triggering
        throttle_minutes (PositiveIntegerField): Minimum time between notifications
        last_triggered (DateTimeField): When this rule was last triggered
        priority (IntegerField): Rule priority for ordering
    r   TzName for this notification rulerZ   r[   r\   r]   r^   r_   r`   )Zhigh_error_ratezHigh Error Rate)Zsystem_startupzSystem Startup)Zsystem_shutdownzSystem Shutdownr    z2Type of event that triggers this notification ruler   Zrulesz*Default notification channel for this ruler&   z+Default notification template for this rulez(Whether this notification rule is activer   z5Additional conditions that must be met for triggeringr   r%   r   i  z4Minimum minutes between notifications from this ruler"   z!When this rule was last triggeredrv   z=Rule priority for ordering (higher numbers = higher priority)c                   @   sD   e Zd ZdZdZddgZejdgdejdgdejdgdgZd	S )
zNotificationRule.MetazNotification RulezNotification Rulesz	-priorityr)   
event_typer+   r-   priorityNr.   r7   r7   r7   r8   r9     s   r9   c                 C   s   | j  d| j dS )z/String representation of the notification rule.r:   r;   )r)   r   r<   r7   r7   r8   r>     s    zNotificationRule.__str__c                 C   s4   | j s
dS | jsdS t | j }| | jd kS )z7Check if the rule can be triggered based on throttling.FT<   )r-   last_triggeredr   r   total_secondsthrottle_minutes)r=   Ztime_since_lastr7   r7   r8   can_trigger  s    zNotificationRule.can_triggerc                 C   s   t  | _| jdgd dS )z0Mark the rule as triggered and update timestamp.r   r   N)r   r   r   r   r<   r7   r7   r8   mark_triggered	  s    
zNotificationRule.mark_triggeredc                 C   sB   | j s
dS | j  D ](\}}||kr* dS || |kr dS qdS )z
        Check if event data meets the rule conditions.
        
        Args:
            event_data (dict): Event data to check against conditions
            
        Returns:
            bool: True if conditions are met, False otherwise
        TF)
conditionsitems)r=   Z
event_datakeyZexpected_valuer7   r7   r8   check_conditions  s    
z!NotificationRule.check_conditionsN)!r/   r0   r1   rN   r   rO   r)   ZEVENT_TYPESr   rV   r   rW   rx   rY   r   rP   r-   rQ   rR   r   rS   r   r   r   r   r   IntegerFieldr   r9   r>   r   r   r   r7   r7   r7   r8   r     sz   
r   )rN   	django.dbr   django.contrib.auth.modelsr   django.utilsr   django.core.validatorsr   r   Zapps.core.modelsr   r   r	   apps.core.validatorsr
   r   r   r   r   r   jsonr   rY   rs   r   r7   r7   r7   r8   <module>   s   	 }v 