a
    ~i                     @   s   d Z ddlmZmZmZ ddlZeeZG dd de	Z
G dd dZe Zeeddd	d
ZeeeeeedddZeedddZdS )zg
Secure event handler registry.

Replaces dangerous eval() pattern with explicit handler registration.
    )CallableDictAnyNc                   @   s   e Zd ZdZdS )InvalidEventErrorz<Raised when attempting to call invalid or unregistered eventN)__name__
__module____qualname____doc__ r
   r
   //var/www/lichun.app/lichun/ws/event_handlers.pyr      s   r   c                   @   sd   e Zd ZdZdd ZeeddddZeeeeeedd	d
Z	ee
dddZee dddZdS )EventHandlerRegistryz
    Registry for secure event handler dispatch.

    Usage:
        registry = EventHandlerRegistry()
        registry.register("characterSetup", characterSetup)
        result = registry.call("characterSetup", player, "answer", key, message)
    c                 C   s
   i | _ d S )N	_handlersselfr
   r
   r   __init__   s    zEventHandlerRegistry.__init__N
event_typehandlerreturnc                 C   s   |rt |tstd| t|s2td| d|v sD|drRtd| || jv rrtd| d dS || j|< td	|  dS )
z"Register an event handler functionInvalid event type: zHandler must be callable: ___z.Event type cannot contain __ or start with _: zEvent handler z4 already registered, skipping duplicate registrationNzRegistered event handler: )
isinstancestr
ValueErrorcallable
startswithr   loggerdebug)r   r   r   r
   r
   r   register   s    

zEventHandlerRegistry.registerr   playermodekeymessager   c              
   C   s   |rt |tstd| d|v s.|dr<td| | j|}|du r^td| z|||||W S  ty } z(tjd| d| d	d
  W Y d}~n
d}~0 0 dS )a  
        Safely call a registered event handler.

        Args:
            event_type: The event type to dispatch
            player: Player object
            mode: Mode string (usually "answer")
            key: Event key
            message: Event message

        Returns:
            Result from handler function

        Raises:
            InvalidEventError: If event type is not registered or invalid
        r   r   r   zDangerous event type rejected: Nz!No handler registered for event: zError calling handler z: T)exc_info)	r   r   r   r   r   get	Exceptionr   error)r   r   r"   r#   r$   r%   r   er
   r
   r   call3   s    zEventHandlerRegistry.callr   r   c                 C   s
   || j v S )z$Check if an event type is registeredr   )r   r   r
   r
   r   is_registeredX   s    z"EventHandlerRegistry.is_registered)r   c                 C   s   t | j S )zList all registered event types)listr   keysr   r
   r
   r   list_events\   s    z EventHandlerRegistry.list_events)r   r   r   r	   r   r   r   r    r   r+   boolr-   r.   r0   r
   r
   r
   r   r      s   	%r   r   c                 C   s   t | | dS )z0Register an event handler in the global registryN)	_registryr    )r   r   r
   r
   r   register_event_handlere   s    r3   r!   c                 C   s   t | ||||S )z.Call an event handler from the global registry)r2   r+   )r   r"   r#   r$   r%   r
   r
   r   call_event_handlerj   s    r4   r,   c                 C   s
   t | S )z6Check if an event is registered in the global registry)r2   r-   )r   r
   r
   r   is_event_registeredo   s    r5   )r	   typingr   r   r   logging	getLoggerr   r   r(   r   r   r2   r   r3   r4   r1   r5   r
   r
   r
   r   <module>   s   
P