
    iw              	       :   d dl Z 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dZdZdZdZdZdZeez   Zeez   ez   ez   ez   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.dZ&d Z'd.dZ(dddddd defd!Z)	 	 d/dd"de*fd#Z+de*fd$Z,	 	 	 	 d0de*fd%Z-	 	 	 	 d0de*fd&Z.d'e"dee j                  fd(Z/d'e"de0fd)Z1d'e"de0fd*Z2d'e"de0fd+Z3d'e"de0fd,Z4dS )1    N)Optional)parser)relativedelta)utils)	FlagValue)convert_to_datetime_awareis_valid_regexl   posthogis_not)exactr   is_set
is_not_set)	icontainsnot_icontainsregex	not_regexgtgteltlteis_date_beforeis_date_after)	semver_eq
semver_neq	semver_gt
semver_gte	semver_lt
semver_lte)semver_tildesemver_caretsemver_wildcardc                       e Zd ZdS )InconclusiveMatchErrorN)__name__
__module____qualname__     H/var/www/icac/venv/lib/python3.11/site-packages/posthog/feature_flags.pyr%   r%   .   s        Dr*   r%   c                       e Zd ZdZdS )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-   2   s          	Dr*   r-    keybucketing_valuesaltreturnc                     |  d| | }t          t          j        |                    d                                                    d d         d          }|t
          z  S )N.zutf-8      )inthashlibsha1encode	hexdigest__LONG_SCALE__)r0   r1   r2   hash_keyhash_vals        r+   _hashr@   B   s_    /////H7< 8 899CCEEcrcJBOOHn$$r*   c                     t          | d         |d          }t          |           D ]$}||d         k    r||d         k     r
|d         c S %d S )Nr0   variant)r2   	value_min	value_max)r@   variant_lookup_table)flagr1   
hash_valuerB   s       r+   get_matching_variantrH   H   sf    tE{O)DDDJ'-- " "---*w{?S2S2S5>!!!4r*   c                     g }d}|                      d          pi                      d          pi                      d          pg }|D ]1}||d         dz  z   }|                    |||d         d           |}2|S )	Nr   filtersmultivariatevariantsrollout_percentaged   r0   )rC   rD   r0   )getappend)feature_flaglookup_tablerC   multivariatesrB   rD   s         r+   rE   rE   P   s    LI"&&y117R<<^LLRPRWW  	  !  (< = CC	#)GENSS	
 	
 	
 		r*   c                    ||'t          d|                     dd           d          d| vr't          d|                     dd           d          | d         }t          |          d	k    rWt                              d
|                     d                      t          d|                     dd           d          |D ] }||vr|                    |          }	|	sd||<   t          d| d          |	                    d          sd||<   n	 |	                    d          pi }
|
                    d          }||}nt          |	||          }t          |	|||||||          }|||<   n-# t           $ r }d||<   t          d| d|           |d}~ww xY w||         }|t          d| d          |s dS |                     d          }|                     d          }|                     dd          }|rl|j|                    |          }|t          d| d          |dk    rt          ||          S t          d|                     dd           d| d          dS )ai  
    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
        device_id: The device ID for bucketing (optional)

    Returns:
        bool: True if all dependencies in the chain evaluate to True, False otherwise
    Nz$Cannot evaluate flag dependency on 'r0   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activeFrJ   aggregation_group_type_indexcohort_propertiesflags_by_keyevaluation_cache	device_idr1   z': zFlag dependency 'z' was previously inconclusivevalueoperatorr   zFlag 'z5' was not evaluated despite being in dependency chainflag_evaluates_toz' has invalid operator 'T)r%   rO   lenlogdebugresolve_bucketing_valuematch_feature_flag_propertiesmatches_dependency_value)propertyr\   r]   distinct_id
propertiesr[   r^   rV   dep_flag_keydep_flagdep_flag_filters dep_aggregation_group_type_indexdep_bucketing_value
dep_resultecached_resultflag_keyexpected_valuer`   actual_values                       r+   evaluate_flag_dependencyrv   _   s   0 /7$~8<<y3Q3Q~~~
 
 	

 ))${X\\%-K-K{{{
 
 	
   23 !!		QHLL<O<OQQRRR$Whll5)6T6TWWW
 
 	

 ) 8 8///#''55H )!15 .,gggg  
  ||H-- !!5:$\22!+3<<	+B+B+Hb(;K;O;O:< <8 <G 3>//2I (+y3 3/ &C$'&.?)5-=&/,?	& 	& 	&
 :D(661 ! ! !9=(64TTTQRTT  !! )6 (OLOOO    	55	 ||E""H\\'**N||J00H N.'++H55(XXXX   ***+NLIII )teY1O1Ottiqttt  
 4s   AE<<
F&F!!F&c                    t          |t                    rGt          |          dk    r4t          | t                    r| S t          | t                    r|| k    S dS t          |t                    rt          | t                    r|| k    S dS )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strrb   bool)rt   ru   s     r+   rg   rg      s      ,$$ .\):):Q)>)>nd++ 	!!,, 	>115 
L$	'	' .J~t,L,L .~-- 5r*   c                     |                      d          pi }|                      d          p|                     d          }|dk    r|st          d          |S |S )a  Resolve the bucketing value for a flag based on its bucketing_identifier setting.

    Returns:
        The appropriate identifier string to use for hashing/bucketing.

    Raises:
        InconclusiveMatchError: If the flag requires device_id but none was provided.
    rJ   bucketing_identifierr^   z;Flag requires device_id for bucketing but none was provided)rO   r%   )rF   ri   r^   flag_filtersr|   s        r+   re   re     s     88I&&,"L88$:;; |?O?O@ @ {** 	(M   r*   rZ   c                :   |-t          j        dt          d           t          | ||          }|                     d          pi }|                    d          pg }	d}
|pi }|                    d          pi                     d          pg }d	 |D             }|	D ]k}	 t          | ||||||||
	  	        r4|                    d          }|r||v r|}nt          | |          }|pdc S P# t          $ r  t          $ r d}
Y hw xY w|
rt          d          dS )NzCalling match_feature_flag_properties() without bucketing_value is deprecated. Pass bucketing_value explicitly. This fallback will be removed in a future major release.   )
stacklevelrJ   groupsFrK   rL   c                     g | ]
}|d          S )r0   r)   ).0rB   s     r+   
<listcomp>z1match_feature_flag_properties.<locals>.<listcomp>8  s    FFFW'%.FFFr*   )r1   r^   rB   TzGCan't determine if feature flag is enabled or not with given properties)	warningswarnDeprecationWarningre   rO   is_condition_matchrH   r-   r%   )rF   ri   rj   r[   r\   r]   r^   r1   r}   flag_conditionsis_inconclusiveflag_variantsvalid_variant_keys	conditionvariant_overriderB   s                   r+   rf   rf     s    h		
 	
 	
 	
 2$YOO88I&&,"L"&&x006BOO)/R!%%n55;@@LLRPRMFFFFF$ # #		# "!  /#
 
 
 ' $-==#;#; # J(8<N(N(N.GG24IIG$&&&!'" ( 	 	 	% 	# 	# 	# #OOO	#
  
$U
 
 	
 5s   !A	C..DDr^   c          
         |                     d          }	t          |                     d          pg           dk    r|                     d          D ]f}
|
                     d          }|dk    rt          |
||||||          }n-|dk    rt          |
||||||          }nt	          |
|          }|s dS g|	d	S |	t          | d
         |          |	dz  k    rdS d	S )NrM   rj   r   typecohortr   rF   FTr0   rN   )rO   rb   match_cohortrv   match_propertyr@   )rQ   ri   r   rj   r[   r\   r]   r1   r^   rM   propproperty_typematchess                r+   r   r   a  sA    #';<<
9==&&,"--11MM,// 	 	D HHV,,M((&% $'   &((2 $%'   )z:: uu %4%%U_+ +	c	!+# +# u4r*   c                    |                      d          }|                      d          pd}|                      d          }|t          vrt          d|           ||vrt          d          |dk    rt          d          ||         }|t          vr|d	S |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    r_t          t          |                    oBt          j	        t          |                    
                    t          |                    d uS |dk    r_t          t          |                    oBt          j	        t          |                    
                    t          |                    d u S |dv rd }d }	 t          |          }n# t          $ r Y nw xY w|>|<t          |t                    r ||t          |          |          S  ||||          S  |t          |          t          |          |          S |dv r	 t          t          |                    }	|	s0t          j        t          |                    }	t#          |	          }	n"# t          $ r}
t          d          |
d }
~
ww xY w|	st          d          t          |t$          j                  r!t#          |          }|dk    r||	k     S ||	k    S t          |t$          j                  r6|dk    r||	                                k     S ||	                                k    S t          |t                    rS	 t          j        |          }t#          |          }|dk    r||	k     S ||	k    S # t          $ r t          d          w xY wt          d          |t(          v r	 t+          |          }n(# t,          t.          f$ r t          d| d          w xY w|t0          v r	 t+          |          }n(# t,          t.          f$ r t          d| d          w xY w|dk    r||k    S |dk    r||k    S |dk    r||k    S |dk    r||k    S |dk    r||k     S |d k    r||k    S n|d!k    rY	 t3          t          |                    \  }}n(# t,          t.          f$ r t          d| d"          w xY w||cxk    o|k     nc S |d#k    rY	 t5          t          |                    \  }}n(# t,          t.          f$ r t          d| d$          w xY w||cxk    o|k     nc S |d%k    rY	 t7          t          |                    \  }}n(# t,          t.          f$ r t          d| d&          w xY w||cxk    o|k     nc S t          d|           )'Nr0   r`   r   r_   zUnknown operator z5can't match properties without a given property valuer   z/can't match properties with operator is_not_setF)r   r   c                     t          | t                    r-t          |                                          d | D             v S t	          j        | |          S )Nc                 P    g | ]#}t          |                                          $S r)   )ry   casefold)r   vals     r+   r   z?match_property.<locals>.compute_exact_match.<locals>.<listcomp>  s7     : : :,/CHH%%'': : :r*   )rx   listry   r   r   str_iequals)r_   override_values     r+   compute_exact_matchz+match_property.<locals>.compute_exact_match  sf    %&& >**3355 : :38: : :   $UN;;;r*   r   r   r   r   r   r   c                     |dk    r| |k    S |dk    r| |k    S |dk    r| |k     S |dk    r| |k    S t          d|           )Nr   r   r   r   zInvalid operator: )
ValueError)lhsrhsr`   s      r+   comparezmatch_property.<locals>.compare  sm    4Sy U""cz!T!!Sy U""cz! !@h!@!@AAAr*   r   z.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Person property value 'z' is not a valid semverzFlag semver value 'r   r   r   r   r   r    r!   z!' is not valid for tilde operatorr"   z!' is not valid for caret operatorr#   z$' is not valid for wildcard operator)rO   PROPERTY_OPERATORSr%   NONE_VALUES_ALLOWED_OPERATORSr   str_icontainsr	   ry   recompilesearchfloat	Exceptionrx   -relative_date_parse_for_feature_flag_matchingr   parser   datetimedateSEMVER_OPERATORSparse_semverr   	TypeErrorSEMVER_COMPARISON_OPERATORS_tilde_bounds_caret_bounds_wildcard_bounds)rh   property_valuesr0   r`   r_   r   r   r   parsed_valueparsed_daterq   override_dateoverride_parsedflag_parsedloweruppers                   r+   r   r     s    ,,u

C||J''27HLL!!E)))$%C%C%CDDD
/!!$C
 
 	
 <$%VWWW$S)N555>;Qu&&&	< 	< 	< w&&un===**5.AAAA8o%%;">5999?""&~u====73u::&& O
3u::&&--c..A.ABB$N	

 ;3u::&& K
3u::&&--c..A.ABBdJ	

 ---
	B 
	B 
	B 	 <<LL 	 	 	D	 #(B.#.. Gw~s5zz8DDDw~|XFFF73~..E

HEEE666		GE

SSK E$l3u::667DD 	 	 	(@ 	
  	(@   nh&788 	5nEEM+++${22${2266 	+++%(8(8(:(:::%(8(8(:(:::,, 	X &^ < < 9- H H///(;66(;66 X X X,-VWWWX )C   ###	*>::OOI& 	 	 	(Q.QQQ  	
 222*511	*   ,H%HHH  
 ;&&&+55\))&+55[((&44\))&+55[((&44\))&+55 * '',SZZ88uu	*   ,R%RRR   O3333e33333'',SZZ88uu	*   ,R%RRR   O3333e33333***/E

;;uu	*   ,U%UUU   O3333e33333 !!?X!?!?
@
@@sy   G% %
G21G2"AJ1 1
K;KK.N: 4N: :O1P %P&3Q %Q(<S %TT; ;%U :V %V?c           	          t          |                     d                    }||vrt          d| d          ||         }t          |||||||          S )Nr_   zcohort zT not found in local cohorts - likely a static cohort that requires server evaluationr   )ry   rO   r-   match_property_group)	rh   r   r[   r\   r]   ri   r^   	cohort_idproperty_groups	            r+   r   r   T  s    $ HLL))**I)))&uiuuu
 
 	
 'y1N   r*   c           
         | sdS |                      d          }|                      d          }|rt          |          dk    rdS d}	d|d         v r|D ]m}
	 t          |
||||||          }|dk    r|s dS n|r dS +# t          $ r  t          $ r,}t
                              d|
 d	|            d}	Y d }~fd }~ww xY w|	rt	          d
          |dk    S |D ]}
	 |
                     d          dk    rt          |
||||||          }n@|
                     d          dk    rt          |
||||||          }nt          |
|          }|
                     dd          }|dk    r|s|s dS |r|r dS n|r|s dS |s|r dS # t          $ r  t          $ r,}t
                              d|
 d	|            d}	Y d }~d }~ww xY w|	rt	          d          |dk    S )NTr   valuesr   Fr   ANDzFailed to compute property z
 locally: z8Can't match cohort without a given cohort property valuer   rF   negationz8can't match cohort without a given cohort property value)
rO   rb   r   r-   r%   rc   rd   r   rv   r   )r   r   r[   r\   r]   ri   r^   property_group_typerj   error_matching_locallyr   r   rq   r   s                 r+   r   r   x  s1     t(,,V44##H--J ZA--t":a=   	. 	.D..#% $'   '%//" %$uu%  $#tt+   ) . . .		KKKKKLLL)-&&&&&&. " 	(J   #e++  ,	. ,	.D+.88F##x//*')$(#"+  GG XXf%%//6$(#')"+  GG -T?CCG88J66&%//" %8 %$uu %8 %$uu  $x $#tt" $x $#tt+   ) . . .		KKKKKLLL)-&&&&&&. " 	(J  
 #e++sI   A?8A??B?"B::B?BF1F8F FG"GGr_   c                    d}t          j        ||           }t          j                            t          j        j                  }|rt          |                    d                    }|dk    rd S |                    d          }|dk    r|t          |          z
  }nj|dk    r|t          |          z
  }nP|d	k    r|t          |
          z
  }n6|dk    r|t          |          z
  }n|dk    r|t          |          z
  }nd S |S d S )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utcr8   groupr   )r_   r   match	parsed_dtr   r   s         r+   r   r     s(    9EIeU##E!%%h&7&;<<I U[[**++V4;;z**s??!M$?$?$??II__!Mv$>$>$>>II__!M$?$?$??II__!M$@$@$@@II__!M$?$?$??II4tr*   c                 *   t          |                                                               d          }|                    d          d                             d          d         }|                    d          }|r|d         st	          d          t          |d                   }t          |          dk    r|d         rt          |d                   nd}t          |          dk    r|d         rt          |d                   nd}|||fS )	a.  Parse a semver string into a comparable (major, minor, patch) integer tuple.

    Matches the behavior of the sortableSemver HogQL function:
    - Handles v-prefix, whitespace, pre-release suffixes
    - Defaults missing components to 0 (e.g., 1.2 -> 1.2.0)
    Raises ValueError if parsing fails.
    vV-r   +r5   zInvalid semver format   r   )ry   striplstripsplitr   r8   rb   )r_   textpartsmajorminorpatchs         r+   r   r     s     u::$$T**D::c??1##C((+DJJsOOE 2a 20111aMME ZZ!^^a^CaMMMaE ZZ!^^a^CaMMMaE5%  r*   c                 B    t          |           \  }}}|||f||dz   dffS )z9~1.2.3 means >=1.2.3 <1.3.0 (allows patch-level changes).r   r   r   )r_   r   r   r   s       r+   r   r     s3    &u--E5%5% 5%!)Q"777r*   c                     t          |           \  }}}|||f}|dk    r	|dz   ddf}n|dk    r	d|dz   df}ndd|dz   f}||fS )zCaret follows semver spec:
    ^1.2.3 means >=1.2.3 <2.0.0
    ^0.2.3 means >=0.2.3 <0.3.0
    ^0.0.3 means >=0.0.3 <0.0.4
    r   r   r   )r_   r   r   r   r   r   s         r+   r   r   $  st     'u--E5%E5!EqyyAq!	EAIq!Auqy!%<r*   c                    t          |                                                               d                              dd                              d          }|st          d          d |                    d          D             }|st          d          t          |          dk    r"t          |d                   }|ddf|dz   ddffS t          |          d	k    r7t          |d                   t          |d                   }}||df||dz   dffS t          |d                   t          |d                   t          |d	                   }}}|||f|||dz   ffS )
zSWildcard matching:
    1.* means >=1.0.0 <2.0.0
    1.2.* means >=1.2.0 <1.3.0
    r   *r/   r5   zInvalid wildcard patternc                     g | ]}||S r)   r)   )r   ps     r+   r   z$_wildcard_bounds.<locals>.<listcomp>@  s    0001a0Q000r*   r   r   r   )	ry   r   r   replacerstripr   r   rb   r8   )r_   cleanedr   r   r   r   s         r+   r   r   7  s_   
 %jj  ''--55c2>>EEcJJG 5344400c**000E 53444
5zzQE!Hq!}uqy!Q///	Uq58}}c%(mmuua 5%!)Q"777!%(mmSq]]CaMMeuue$ueUQY&???r*   )r/   )N)NN)NNNN)5r   r9   loggingr   r   typingr   dateutilr   dateutil.relativedeltar   r
   r   posthog.typesr   posthog.utilsr   r	   r   r=   	getLoggerrc   r   EQUALITY_OPERATORSSTRING_OPERATORSNUMERIC_OPERATORSDATE_OPERATORSr   SEMVER_RANGE_OPERATORSr   r   r   r%   r-   ry   r@   rH   rE   rv   rg   re   rf   rz   r   r   r   r   r   tupler   r   r   r   r)   r*   r+   <module>r     s      				              0 0 0 0 0 0       # # # # # # C C C C C C C C())g	""!)
  A G . 4  M .1GG    	 	 	 	 	 	Y 	 	 			 		 		 		 		y 		 		 		 % %s %S % %U % % % %    , D D D DN  D   6 @ @ @ @ @ @ @R 1 1 1 1 
1 1 1 1h|A |A |A |A |AF ! ! 
! ! ! !P l, l, 
l, l, l, l,^h    @! ! ! ! ! !.8 8 8 8 8 8     &@C @E @ @ @ @ @ @r*   