
    ib                         d Z ddlZddlZddlmZmZ ddlmZmZmZm	Z	 ddl
ZddlmZmZ ddlmZmZ ddlmZmZ dd	lmZ  ej.                  d
      Z	 ddee   dededeeef   fdZdee   dedefdZy)z
Suppression engine: applies validation results to actual forecast data.

Modifies rm_forecast_cache.forecast_data to suppress invalid player props.
Handles rollback (unpublish) when previously-valid props become invalid.
    N)datetimetimezone)ListDictAnyTuple   )ValidationStateAuditAction)PropEligibilityAuditLogEntry)PropEligibilityRepoAuditLogRepo)normalize_player_namezpub-integrityeligibilitiesrun_iddry_runreturnc                 "   dddddg d}i }|D ]-  }|j                  |j                  g       j                  |       / | j                  t        j
                  j                        }|j                         D ]  \  }}	|j                  d|f       |j                         }
|
s-|
d   xs i }|j                  dg       }|sKt               }|	D ]  }|dxx   dz  cc<   |j                  j                  ri|j                  t        |j                                |d	xx   dz  cc<   |d
   j                  |j                   ||j"                  |j$                  d       |j                  t&        j(                  k(  rL|dxx   dz  cc<   |j*                  r|j                  t        |j                                |d	xx   dz  cc<   |dxx   dz  cc<    |sdg }g }|D ]D  }t        |j                  dd            }||v r|j                  |       4|j                  |       F |s|r&t,        j/                  dt1        |       d|        ||d<   ||d<   ||d<   t3        j4                  t6        j8                        j;                         |d<   |j                  dt=        j>                  |      |
d   f       |dxx   dz  cc<   t,        j/                  d| dt1        |       dt1        |              |	D ]  }|j                  j                  s+|j                  t&        j(                  k(  s7|j*                  rDtA        jB                  | ||jD                        }tG        jH                  | tK        |||jD                  |j                   |jL                  |jN                  tP        jR                  |j                  |j"                  |j$                  |jT                  |jV                  |               |jY                          |S )au  
    Apply suppression to forecast data based on eligibility results.

    For each event with suppressed props:
    1. Load forecast_data from rm_forecast_cache
    2. Filter prop_highlights to only include eligible players
    3. Store suppressed props in a separate field for audit
    4. Update the forecast_data JSONB

    Returns stats about what was suppressed.
    r   )total_propsverified
suppressedpending_lineupevents_modifiedsuppressionscursor_factoryY
            SELECT id, forecast_data FROM rm_forecast_cache WHERE event_id = %s
        forecast_dataprop_highlightsr   r	   r   r   )playerevent_idreasondetailr   r   r!    z[DRY RUN] Would suppress z
 props in _suppressed_props_suppression_run_id_suppression_atS
            UPDATE rm_forecast_cache SET forecast_data = %s WHERE id = %s
        idr   z[suppress] z: kept z props, suppressed )r   game_id	player_idplayer_nameteam_idleagueactionvalidation_statesuppress_reasonsuppress_reason_humanwinning_sourceconflict_payloadprior_state)-
setdefaultr+   appendcursorpsycopg2extrasRealDictCursoritemsexecutefetchonegetsetr1   is_suppressedaddr   r-   r2   r3   r
   VERIFIED_PENDING_LINEUPpublish_allowedloginfolenr   nowr   utc	isoformatjsondumpsr   get_prior_stater,   r   insertr   r.   r/   r   
SUPPRESSEDr4   r5   close)connr   r   r   statsby_eventeligcurr"   event_eligsrowfdr    suppress_namesverified_propssuppressed_propsproppnamepriors                      K/var/www/html/rainmaker/backend/scripts/publishing_integrity/suppression.pysuppress_ineligible_propsra      s   $ E 24H ;DLL"-44T:; ++X__%C%C+
DC!)!1 \+ [	 lln!'R&&!2B7  	'D- A% $$22""#89I9I#JKl#q(#n%,,".. ("22"88	.  &&/*Q*QQ&'1,'++"&&'<T=M=M'NO,'1,'j!Q&!#	'&  # 	,D)$((8R*@AE& ''-%%d+	,  HH05E1F0GzRZQ[\] !/"2$* ! (X\\ : D D F jjnc$i(	* 	 A% (73~+>*? @./02	
   	D$$22%%)P)PP,,+;;D(DNN[##D-!$"nn $ 0 0 LL;;&11%)%:%:$($8$8*.*D*D#'#6#6%)%:%: %+ 	Q\| IIKL    c                 4   d}| j                  t        j                  j                        }i }|D ]K  }|j                  t
        j                  k(  s!|j                  |j                  g       j                  |       M |j                         D ]  \  }}|j                  d|f       |j                         }	|	s-|	d   xs i }
|
j                  dg       }|sK|D ch c]  }t        |j                         }}g }g }|D ]D  }t        |j                  dd            }||v r|j                  |       4|j                  |       F |s|
j                  dg       }||z   |
d<   ||
d<   t!        j"                  t$        j&                        j)                         |
d	<   |j                  d
t+        j,                  |
      |	d   f       |t/        |      z  }t0        j3                  d| dt/        |       d       |D ]  }t5        j6                  | t9        ||t        |j                  dd            |j                  dd      d|
j                  dd      t:        j<                  t
        j                  d	               |j?                          |S c c}w )zf
    Restore previously-suppressed props that are now valid.
    Returns count of restored props.
    r   r   r   r   r&   r!   r%   r    _last_restore_atr)   r*   z
[restore] z: restored z previously suppressed propsr/   rP   )	r   r+   r,   r-   r.   r/   r0   r1   r6   ) r9   r:   r;   r<   r1   r
   VERIFIEDr7   r+   r8   r=   r>   r?   r@   r   r-   r   rI   r   rJ   rK   rL   rM   rH   rF   rG   r   rO   r   r   	PUBLISHEDrQ   )rR   r   r   restoredrV   rT   rU   r"   rW   rX   rY   r   everified_names
to_restorestill_suppressedr]   r^   current_propss                      r`   restore_props_if_validrm      s    H
++X__%C%C+
DC13H ?  O$<$<<b188>? "*!1 5+ [	 lln!'RVV/4
 ITT1/>TT
 	.D)$((8R*@AE&!!$' ''-	.  0"5 -
 :"2!)hll!;!E!E!G jjnc$i(	* 	C
O#:hZ{3z?2CC_`a  	Dm /20FG HHXr2vvh+",,!0!9!9(
' 
	U5n IIKOU Us   J)F)__doc__rL   loggingr   r   typingr   r   r   r   psycopg2.extrasr:   enumsr
   r   modelsr   r   repositoriesr   r   normalizationr   	getLoggerrF   strboolra   intrm    rb   r`   <module>r{      s      ' ) )  / 2 ; 0g( 	@(@ @ 	@
 
#s(^@FI(I I 		Irb   