U
    Hif                     @   s`   d dl Z d dlmZmZmZ d dlmZ d dlmZ d dl	m
Z
 G dd dZG dd	 d	ZdS )
    N)OptionalCallable	Awaitable)	WebSocket)WebSocketDisconnect)Logc                   @   s4   e Zd ZdZdd ZddddZdddd	ZdS )
ConnectionStateay  
    Tracks the current Mcube call session and manages connection state.
    
    - Holds the current stream ID and call ID for the active Mcube call session.
    - Provides methods to reset or clear state when a new call starts or an interruption occurs.
    
    Audio-related state is now managed by AudioService, so this class focuses only on connection/session state.
    c                 C   s   d | _ d | _d S N)	stream_idcall_idself r   @/var/www/html/live_calls/homebook/services/connection_manager.py__init__   s    zConnectionState.__init__Nreturnc                 C   s   dS )z%Reset state when a new stream starts.Nr   r   r   r   r   reset_stream_state   s    z"ConnectionState.reset_stream_statec                 C   s   dS )z2Clear response-related state during interruptions.Nr   r   r   r   r   clear_response_state   s    z$ConnectionState.clear_response_state)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   	   s   	r   c                   @   s   e Zd ZdZedddZeddddZeege	d f eege	d f ee
ge	d f dd	d
dZe
ddddZddddZdeee
 ddddZdS )WebSocketConnectionManagera  
    Orchestrates WebSocket communication between Mcube and ElevenLabs for Service Type 4.
    
    - Establishes, maintains, and closes WebSocket connections to Mcube (FastAPI).
    - Routes incoming messages to appropriate event handlers for media, start, and playedStream events.
    - Sends and receives messages, manages connection state, and coordinates with AudioService for checkpoint/clear events.
    
    This is the main interface for real-time, bidirectional communication between Mcube and ElevenLabs.
    )mcube_wsc                 C   s   || _ t | _d S r	   )r   r   state)r   r   r   r   r   r   -   s    z#WebSocketConnectionManager.__init__N)messager   c              
      s   z*| j jjdkrW dS | j |I dH  W n tk
r } zft| }d|ksd|ksd|krbn<ddl}t	d|  t	d|  t	d	|
   W 5 d}~X Y nX dS )
z"Send a message to Mcube WebSocket.	CONNECTEDNnot connectedclosedacceptr   u'   ⚠️ Error sending message to Mcube: z	Message: zFull traceback: )r   client_statename	send_json	Exceptionstrlower	tracebackr   warning
format_exc)r   r   e	error_strr'   r   r   r   send_to_mcube1   s    z(WebSocketConnectionManager.send_to_mcube)on_mediaon_starton_played_streamr   c              
      s  z6| j jjdkrW dS | j  2 z3 dH W }| j jjdkrD q6t|}|d dkrj||I dH  q"|d dkr
|di }|d}|d}|| j_|| j_	|rt
d||d	 n0zt
d
| W n tk
r   t
d Y nX | j  ||I dH  q"|d dkr"|d}	|	r"||	I dH  q"6 W n~ tk
rX   t
d Y n` tk
r }
 z@t|
 }d|ksd|ksd|krnt
d|
  W 5 d}
~
X Y nX dS )a&  
        Receive messages from Mcube and route them to appropriate handlers.
        
        Args:
            on_media: Handler for media events
            on_start: Handler for call start events (now receives full data)
            on_played_stream: Handler for playedStream events
        r   NeventmediastartstreamIdcallIdzMcube Start)r3   r4   zMcube Start (no callId)zCMcube start payload (no callId) and failed to serialize start_info.playedStreamr"   z'Mcube WebSocket disconnected (expected)r   r    r   zError in receive_from_mcube: )r   r!   r"   	iter_textjsonloadsgetr   r
   r   r   r0   r$   errorr   r   infor%   r&   )r   r-   r.   r/   r   dataZ
start_infor
   r   r"   r*   r+   r   r   r   receive_from_mcubeD   sJ    





z-WebSocketConnectionManager.receive_from_mcube)r"   r   c                    s>   | j jr:ddlm} | }|| j j|}| |I dH  dS )z4Send a checkpoint event to Mcube using AudioService.r   AudioServiceN)r   r
   services.audio_servicer?   create_checkpoint_messager,   )r   r"   r?   audio_serviceZcheckpoint_eventr   r   r   send_checkpoint_to_mcube   s
    z3WebSocketConnectionManager.send_checkpoint_to_mcuber   c                    s<   | j jr8ddlm} | }|| j j}| |I dH  dS )z/Clear audio buffer in Mcube using AudioService.r   r>   N)r   r
   r@   r?   create_clear_messager,   )r   r?   rB   Zclear_eventr   r   r   clear_mcube_audio   s
    z,WebSocketConnectionManager.clear_mcube_audio  )codereasonr   c              
      s`   z(| j j||pddI dH  td W n2 tk
rZ } ztd|  W 5 d}~X Y nX dS )zeClose the Mcube WebSocket connection gracefully.
        This ends the call on Mcube's side.
        znormal closure)rG   rH   Nz!Closed Mcube WebSocket connectionz!Failed to close Mcube WebSocket: )r   closer   r;   r$   r:   )r   rG   rH   r*   r   r   r   close_mcube_connection   s
    z1WebSocketConnectionManager.close_mcube_connection)rF   N)r   r   r   r   r   r   dictr,   r   r   r%   r=   rC   rE   intr   rJ   r   r   r   r   r   "   s   
B		r   )r7   typingr   r   r   fastapir   fastapi.websocketsr   services.log_utilsr   r   r   r   r   r   r   <module>   s   