o
    i%                     @   s   d Z ddlZddlmZ ddlmZ ddlmZmZm	Z	m
Z
mZmZ ddlmZ ddlmZ ddlmZ dd	lmZmZ eG d
d dZeG dd dZeG dd dZG dd deZG dd dZdS )zSmallWebRTC request handler for managing peer connections.

This module provides a client for handling web requests and managing WebRTC connections.
    N)	dataclass)Enum)Any	AwaitableCallableDictListOptional)candidate_from_sdp)HTTPException)logger)	IceServerSmallWebRTCConnectionc                   @   sd   e Zd ZU dZeed< eed< dZee ed< dZee	 ed< dZ
ee ed< edefd	d
ZdS )SmallWebRTCRequesta  Small WebRTC transport session arguments for the runner.

    Parameters:
        sdp: The SDP string (Session Description Protocol).
        type: The type of the SDP, either "offer" or "answer".
        pc_id: Optional identifier for the peer connection.
        restart_pc: Optional whether to restart the peer connection.
        request_data: Optional custom data sent by the customer.
    sdptypeNpc_id
restart_pcrequest_datadatac                 C   s,   d|v rd|vr| d|d< | di |S )z@Accept both snake_case and camelCase for the request_data field.requestDatar   N )pop)clsr   r   r   b/home/ubuntu/.local/lib/python3.10/site-packages/pipecat/transports/smallwebrtc/request_handler.py	from_dict*   s   zSmallWebRTCRequest.from_dict)__name__
__module____qualname____doc__str__annotations__r   r	   r   boolr   r   classmethoddictr   r   r   r   r   r      s   
 
r   c                   @   s*   e Zd ZU dZeed< eed< eed< dS )IceCandidatea*  The remote ice candidate object received from the peer connection.

    Parameters:
        candidate: The ice candidate patch SDP string (Session Description Protocol).
        sdp_mid: The SDP mid for the candidate patch.
        sdp_mline_index: The SDP mline index for the candidate patch.
    	candidatesdp_midsdp_mline_indexN)r   r   r   r   r    r!   intr   r   r   r   r%   2   s
   
 r%   c                   @   s&   e Zd ZU dZeed< ee ed< dS )SmallWebRTCPatchRequestzSmall WebRTC transport session arguments for the runner.

    Parameters:
        pc_id: Identifier for the peer connection.
        candidates: A list of ICE candidate patches.
    r   
candidatesN)r   r   r   r   r    r!   r   r%   r   r   r   r   r*   A   s   
 r*   c                   @   s   e Zd ZdZdZdZdS )ConnectionModez,Enum defining the connection handling modes.singlemultipleN)r   r   r   r   SINGLEMULTIPLEr   r   r   r   r,   N   s    r,   c                   @   s   e Zd ZdZdddejfdeee  de	dee
 deddf
d	d
Zdee
 ddfddZddeee  fddZdedeeged f deee
e
f  fddZdefddZdd ZdS )SmallWebRTCRequestHandlera  SmallWebRTC request handler for managing peer connections.

    This class is responsible for:
      - Handling incoming SmallWebRTC requests.
      - Creating and managing WebRTC peer connections.
      - Supporting ESP32-specific SDP munging if enabled.
      - Invoking callbacks for newly initialized connections.
      - Supporting both single and multiple connection modes.
    NFice_servers
esp32_modehostconnection_modereturnc                 C   s"   || _ || _|| _|| _i | _dS )a7  Initialize a SmallWebRTC request handler.

        Args:
            ice_servers (Optional[List[IceServer]]): List of ICE servers to use for WebRTC
                connections.
            esp32_mode (bool): If True, enables ESP32-specific SDP munging.
            host (Optional[str]): Host address used for SDP munging in ESP32 mode.
                Ignored if `esp32_mode` is False.
            connection_mode (ConnectionMode): Mode of operation for handling connections.
                SINGLE allows only one active connection, MULTIPLE allows several.
        N)_ice_servers_esp32_mode_host_connection_mode_pcs_map)selfr2   r3   r4   r5   r   r   r   __init__`   s
   
z"SmallWebRTCRequestHandler.__init__r   c                 C   s|   | j tjkrdS | jsdS tt| j }|j|kr/|r/t	d|j d|  t
ddd|s<t	d t
ddddS )	a  Check if the connection request satisfies single connection mode constraints.

        Args:
            pc_id: The peer connection ID from the request

        Raises:
            HTTPException: If constraints are violated in single connection mode
        Nz$Connection pc_id mismatch: existing=z, received=i  z'PC ID mismatch with existing connectionstatus_codedetailzMCannot create new connection: existing connection found but no pc_id receivedz<Cannot create new connection with existing connection active)r:   r,   r/   r;   nextitervaluesr   r   warningr   )r<   r   existing_connectionr   r   r   $_check_single_connection_constraintsz   s&   	z>SmallWebRTCRequestHandler._check_single_connection_constraintsc                 C   s
   || _ dS )z;Update the list of ICE servers used for WebRTC connections.N)r7   )r<   r2   r   r   r   update_ice_servers   s   
z,SmallWebRTCRequestHandler.update_ice_serversrequestwebrtc_connection_callbackc              
      s  z|j } | |r j|nd}|r1|}td|  |j|j|j|j	p*ddI dH  nQt
 jd}|j|j|jdI dH  |ddt
f fd	d
}z||I dH  td|j   W n ty } ztd|j  d|  W Y d}~nd}~ww | } jrddlm}	 |	|d  j|d< | j|d < |W S  ty }
 ztd|
  td|   d}
~
ww )aB  Handle a SmallWebRTC request and resolve the pending answer.

        This method will:
          - Reuse an existing WebRTC connection if `pc_id` exists.
          - Otherwise, create a new `SmallWebRTCConnection`.
          - Invoke the provided callback with the connection.
          - Manage ESP32-specific munging if enabled.
          - Enforce single/multiple connection mode constraints.

        Args:
            request (SmallWebRTCRequest): The incoming WebRTC request, containing
                SDP, type, and optionally a `pc_id`.
            webrtc_connection_callback (Callable[[Any], Awaitable[None]]): An
                asynchronous callback function that is invoked with the WebRTC connection.

        Returns:
            Dictionary containing SDP answer, type, and peer connection ID,
            or None if no answer is available.

        Raises:
            HTTPException: If connection mode constraints are violated
            Exception: Any exception raised during request handling or callback execution
                will be logged and propagated.
        Nz'Reusing existing connection for pc_id: F)r   r   r   )r2   )r   r   closedwebrtc_connectionc                    s(   t d| j   j| jd  d S )Nz&Discarding peer connection for pc_id: )r   infor   r;   r   )rK   r<   r   r   handle_disconnected   s   zISmallWebRTCRequestHandler.handle_web_request.<locals>.handle_disconnectedz;webrtc_connection_callback executed successfully for peer: z+webrtc_connection_callback failed for peer z: r   )smallwebrtc_sdp_mungingr   r   z&Error processing SmallWebRTC request: zSmallWebRTC request details: )r   rF   r;   getr   rL   renegotiater   r   r   r   r7   
initializeevent_handlerdebug	Exceptionerror
get_answerr8   pipecat.runner.utilsrO   r9   )r<   rH   rI   r   rE   pipecat_connectionrN   callback_erroranswerrO   er   rM   r   handle_web_request   sP   

z,SmallWebRTCRequestHandler.handle_web_requestc                    sZ   | j |j}|stddd|jD ]}t|j}|j|_|j	|_
||I dH  qdS )z-Handle a SmallWebRTC patch candidate request.i  zPeer connection not foundr>   N)r;   rP   r   r   r+   r
   r&   r'   sdpMidr(   sdpMLineIndexadd_ice_candidate)r<   rH   peer_connectioncr&   r   r   r   handle_patch_request   s   

z.SmallWebRTCRequestHandler.handle_patch_requestc                    s4   dd | j  D }tj| I dH  | j   dS )zClear the connection map.c                 S   s   g | ]}|  qS r   )
disconnect).0pcr   r   r   
<listcomp>   s    z3SmallWebRTCRequestHandler.close.<locals>.<listcomp>N)r;   rC   asynciogatherclear)r<   corosr   r   r   close   s   zSmallWebRTCRequestHandler.close)N)r   r   r   r   r,   r0   r	   r   r   r"   r    r=   rF   rG   r   r   r   r   r   r]   r*   rc   rl   r   r   r   r   r1   U   s8    

!
Qr1   )r   rh   dataclassesr   enumr   typingr   r   r   r   r   r	   
aiortc.sdpr
   fastapir   logurur   )pipecat.transports.smallwebrtc.connectionr   r   r   r%   r*   r,   r1   r   r   r   r   <module>   s"    