
    QiW              	          d dl Z d dlZd dlZd dlZd dlmZ d dl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d      Z ej&                  d	      Zd
gZ G d de      Z G d de      ZddedededefdZd Zd Zd Zd Z	 	 	 d defdZ	 	 d!de fdZ!de fdZ"	 	 	 d de fdZ#	 	 	 d de fdZ$dedee j                      fdZ%y)"    N)Optional)parser)relativedelta)utils)	FlagValue)convert_to_datetime_awareis_valid_regexl   posthogis_notc                       e Zd Zy)InconclusiveMatchErrorN)__name__
__module____qualname__     Q/mnt/e/genesis-system/.venv/lib/python3.12/site-packages/posthog/feature_flags.pyr   r      s    r   r   c                       e Zd ZdZy)RequiresServerEvaluationa&  
    Raised when feature flag evaluation requires server-side data that is not
    available locally (e.g., static cohorts, experience continuity).

    This error should propagate immediately to trigger API fallback, unlike
    InconclusiveMatchError which allows trying other conditions.
    N)r   r   r   __doc__r   r   r   r   r      s     	r   r   keydistinct_idsaltreturnc                     |  d| | }t        t        j                  |j                  d            j	                         d d d      }|t
        z  S )N.zutf-8      )inthashlibsha1encode	hexdigest__LONG_SCALE__)r   r   r   hash_keyhash_vals        r   _hashr'   )   sO    a}TF+H7<< 89CCEcrJBOHn$$r   c                 v    t        | d   |d      }t        |       D ]  }||d   k\  s||d   k  s|d   c S  y )Nr   variant)r   	value_min	value_max)r'   variant_lookup_table)flagr   
hash_valuer)   s       r   get_matching_variantr/   /   sP    tE{Ki@J'- "--*w{?S2S5>!" r   c                     g }d}| j                  d      xs i j                  d      xs i j                  d      xs g }|D ]'  }||d   dz  z   }|j                  |||d   d       |}) |S )	Nr   filtersmultivariatevariantsrollout_percentaged   r   )r*   r+   r   )getappend)feature_flaglookup_tabler*   multivariatesr)   r+   s         r   r,   r,   7   s    LI"&&y17R<<^LRPRWW 	  ! (< = CC	#)GENS	
 	 r   c           	         ||t        d| j                  dd       d      d| vrt        d| j                  dd       d      | d   }t        |      d	k(  rFt        j	                  d
| j                  d              t        d| j                  dd       d      |D ]t  }||vrT|j                  |      }|sd||<   t        d| d      |j                  d      sd||<   n	 t        ||||||      }	|	||<   ||   }|t        d| d      |rt y | j                  d      }| j                  d      }| j                  dd      }|rW|U|j                  |      }|t        d| d      |dk(  rt        ||      S t        d| j                  dd       d| d      y# t         $ r}
d||<   t        d| d|
       |
d}
~
ww xY w)a/  
    Evaluate a flag dependency property according to the dependency chain algorithm.

    Args:
        property: Flag property with type="flag" and dependency_chain
        flags_by_key: Dictionary of all flags by their key
        evaluation_cache: Cache for storing evaluation results
        distinct_id: The distinct ID being evaluated
        properties: Person properties for evaluation
        cohort_properties: Cohort properties for evaluation

    Returns:
        bool: True if all dependencies in the chain evaluate to True, False otherwise
    Nz$Cannot evaluate flag dependency on 'r   unknownz+' without flags_by_key and evaluation_cachedependency_chainzFlag dependency property for 'z.' is missing required 'dependency_chain' fieldr   z'Circular dependency detected for flag: z'Circular dependency detected for flag ''z!Cannot evaluate flag dependency 'z!' - flag not found in local flagsactiveFz': zFlag dependency 'z' was previously inconclusivevalueoperatorexactzFlag 'z5' was not evaluated despite being in dependency chainflag_evaluates_toz' has invalid operator 'T)r   r6   lenlogdebugmatch_feature_flag_propertiesmatches_dependency_value)propertyflags_by_keyevaluation_cacher   
propertiescohort_propertiesr=   dep_flag_keydep_flag
dep_resultecached_resultflag_keyexpected_valuerA   actual_values                   r   evaluate_flag_dependencyrV   F   s   " /7$28<<y3Q2RR}~
 	

 )$,X\\%-K,LLz{
 	
   23 !		;HLL<O;PQR$5hll5)6T5UUVW
 	

 ) *//#''5H15 .,7~Efg 
  ||H-5:$\2!%B$'&-(,&
 :D(6 )6 (#L>1NO  U*\ ||E"H\\'*N||J0HN.'++H5(
"WX  **+NLII )0eY1O0PPhiqhrrst 
 [ 2 !9=(64?~SQRPST !!s   (F''	G0GGc                     t        |t              r6t        |      dkD  r(t        | t              r| S t        | t              r|| k(  S yt        |t              rt        | t              r|| k(  S y)a  
    Check if the actual flag value matches the expected dependency value.

    This follows the same logic as the C# MatchesDependencyValue function:
    - String variant case: check for exact match or boolean true
    - Boolean case: must match expected boolean value

    Args:
        expected_value: The expected value from the property
        actual_value: The actual value returned by the flag evaluation

    Returns:
        bool: True if the values match according to flag dependency rules
    r   F)
isinstancestrrD   bool)rT   rU   s     r   rH   rH      sg      ,$\):Q)>nd+!!,>11 
L$	'J~t,L~-- r   c           
         | j                  d      xs i j                  d      xs g }d}|xs i }| j                  d      xs i j                  d      xs i j                  d      xs g }|D 	cg c]  }	|	d   	 }
}	|D ]B  }	 t        | ||||||      r.|j                  d      }|r||
v r|}	nt        | |      }	|	xs dc S D |rt	        d	      yc c}	w # t        $ r  t        $ r d}Y nw xY w)
Nr1   groupsFr2   r3   r   r)   TzGCan't determine if feature flag is enabled or not with given properties)r6   is_condition_matchr/   r   r   )r-   r   rL   rM   rJ   rK   flag_conditionsis_inconclusiveflag_variantsr)   valid_variant_keys	conditionvariant_overrides                r   rG   rG      sB    xx	*0b55h?E2OO)/Rhhy)/R44^DJOO 	  9FFW'%.FF$ #		# "!  $-==#; #(8<N(N.G24EG$&	#6 $U
 	
 I G* ( 	% 	# #O	#s   0C<CC/.C/c           	      d   |j                  d      }t        |j                  d      xs g       dkD  rf|j                  d      D ]O  }|j                  d      }	|	dk(  rt        ||||||      }
n"|	dk(  rt        ||||||      }
nt	        ||      }
|
rO y |y|t        | d	   |      |d
z  kD  ryy)Nr4   rL   r   typecohortr-   FTr   r5   )r6   rD   match_cohortrV   match_propertyr'   )r8   r   rb   rL   rM   rJ   rK   r4   propproperty_typematchess              r   r]   r]     s     #';<
9==&,"-1MM,/ 	D HHV,M(&% $ &(2 $% )z:/	2 %%%U0C[*QS + r   c                 n   | j                  d      }| j                  d      xs d}| j                  d      }||vrt        d      |dk(  rt        d      ||   }|t        vr|y|d	v rd
 }|dk(  r	 |||      S  |||       S |dk(  r||v S |dk(  rt        j                  ||      S |dk(  rt        j                  ||       S |dk(  rNt        t        |            xr8 t        j                  t        |            j                  t        |            d uS |dk(  rNt        t        |            xr8 t        j                  t        |            j                  t        |            d u S |dv r^d }d }	 t        |      }|/|-t        |t              r ||t        |      |      S  ||||      S  |t        |      t        |      |      S |dv r	 t        t        |            }	|	s)t        j                  t        |            }	t!        |	      }	|	st        d      t        |t"        j"                        rt!        |      }|dk(  r||	k  S ||	kD  S t        |t"        j$                        r+|dk(  r||	j%                         k  S ||	j%                         kD  S t        |t              r0	 t        j                  |      }t!        |      }|dk(  r||	k  S ||	kD  S t        d      t        d|       # t        $ r Y }w xY w# t        $ r}
t        d      |
d }
~
ww xY w# t        $ r t        d      w xY w)Nr   rA   rB   r@   z5can't match properties without a given property value
is_not_setz/can't match properties with operator is_not_setF)rB   r   c                     t        | t              r@t        |      j                         | D cg c]  }t        |      j                          c}v S t	        j
                  | |      S c c}w )N)rX   listrY   casefoldr   str_iequals)r@   override_valuevals      r   compute_exact_matchz+match_property.<locals>.compute_exact_matchU  sa    %&>*33538:,/CH%%':   $$UN;;:s    A'is_set	icontainsnot_icontainsregex	not_regex)gtgteltltec                 n    |dk(  r| |kD  S |dk(  r| |k\  S |dk(  r| |k  S |dk(  r| |k  S t        d|       )Nrz   r{   r|   r}   zInvalid operator: )
ValueError)lhsrhsrA   s      r   comparezmatch_property.<locals>.comparey  s]    4Sy U"cz!T!Sy U"cz! #5hZ!@AAr   )is_date_beforeis_date_afterz.The date set on the flag is not a valid formatr   z'The date provided is not a valid formatz1The date provided must be a string or date objectzUnknown operator )r6   r   NONE_VALUES_ALLOWED_OPERATORSr   str_icontainsr	   rY   recompilesearchfloat	ExceptionrX   -relative_date_parse_for_feature_flag_matchingr   parser   datetimedate)rI   property_valuesr   rA   r@   rr   rt   r   parsed_valueparsed_daterQ   override_dates               r   rh   rh   ?  s    ,,u
C||J'27HLL!E
/!$C
 	
 <$%VWW$S)N55>;Q&&	< w&un==*5.AAA8o%%;"">599?"&&~u===73u:& O

3u:&--c..AB$N	

 ;3u:& K

3u:&--c..ABdJ	

 --
	B 	 <L #(B.#.~s5z8DD~|XFF3~.E
HEE66		GE
SK$ll3u:67D (@  nh&7&785nEM++${22${226++%(8(8(:::%(8(8(:::,X &^ < 9- H//(;66(;66 )C 
 !#4XJ!?
@@o  		$  	(@	:  X,-VWWXs<   6K2 ?L *)L L 2	K?>K?	LLLL4c                     t        | j                  d            }||vrt        d| d      ||   }t        ||||||      S )Nr@   zcohort zT not found in local cohorts - likely a static cohort that requires server evaluation)rY   r6   r   match_property_group)rI   r   rM   rJ   rK   r   	cohort_idproperty_groups           r   rg   rg     se    " HLL)*I))&i[ tu
 	
 'y1N r   c           	          | sy| j                  d      }| j                  d      }|rt        |      dk(  ryd}d|d   v r7|D ]   }		 t        |	|||||      }
|dk(  r|
s y|
r y" |rt	        d	      |dk(  S |D ]  }		 |	j                  d      d
k(  rt        |	|||||      }
n1|	j                  d      dk(  rt        |	|||||      }
nt        |	|      }
|	j                  dd      }|dk(  r|
s|s y|
r|r y|
r|s y|
s|r y |rt	        d      |dk(  S # t        $ r  t        $ r(}t
        j                  d|	 d|        d}Y d }~	d }~ww xY w# t        $ r  t        $ r(}t
        j                  d|	 d|        d}Y d }~d }~ww xY w)NTre   valuesr   FANDzFailed to compute property z
 locally: z8Can't match cohort without a given cohort property valuerf   r-   negationz8can't match cohort without a given cohort property value)
r6   rD   r   r   r   rE   rF   rg   rV   rh   )r   r   rM   rJ   rK   r   property_group_typerL   error_matching_locallyri   rk   rQ   r   s                r   r   r     s    (,,V4##H-JZA-":a=  	.D..#% $ '%/"$ #!	.0 "(J  #e++  *	.D).88F#x/*')$(#G XXf%/6$(#')G -T?CG88J6&%/"8$8$ x#"x#I*	.X "(J 
 #e++C , ) .		7vZsKL)-&.b , ) .		7vZsKL)-&.sI   DD=A1E0E6E<EE(EEF%FFr@   c                    d}t        j                  ||       }t        j                  j                  t        j                  j
                        }|rt        |j                  d            }|dk\  ry |j                  d      }|dk(  r|t        |      z
  }|S |dk(  r|t        |      z
  }|S |d	k(  r|t        |
      z
  }|S |dk(  r|t        |      z
  }|S |dk(  r|t        |      z
  }|S y y )Nz)^-?(?P<number>[0-9]+)(?P<interval>[a-z])$numberi'  intervalh)hoursd)daysw)weeksm)monthsy)years)	r   r   r   nowtimezoneutcr   groupr   )r@   rx   match	parsed_dtr   r   s         r   r   r   O  s    9EIIeU#E!!%%h&7&7&;&;<IU[[*+V;;z*s?!M$??I  _!Mv$>>I  _!M$??I  _!M$@@I  _!M$??I   r   ) )NNN)NN)&r   r    loggingr   typingr   dateutilr   dateutil.relativedeltar   r
   r   posthog.typesr   posthog.utilsr   r	   r   r$   	getLoggerrE   r   r   r   r   rY   r'   r/   r,   rV   rH   rG   rZ   r]   rh   rg   r   r   r   r   r   <module>r      s4      	   0  # C()g	"!)
 	Y 			y 		 %s % %C % %odL 3 3x , 
,^@A @AN  
L h, 
h,Vh r   