
    hJ                        d dl mZmZmZmZ d dlZd dlmZ d dlmZ d dl	Z	d dl
m
Z
mZ d dlZd dlZd dlZd dlZd dlmZmZ d dlZd dlZd dlZd dlZd dl
m
Z
mZ  ej        e          Z G d d          ZdS )	    )capture_exceptioncapture_messageset_tagset_contextN)MongoClientObjectIddatetime	timedelta)MONGODB_URI
MONGODB_DBc                   l   e Zd Zd ZdhdZd Zd Zd Zd Zd Z	d	 Z
dhd
Zd Zd Zd Zd Zd Zd Zd Zd Zd ZdidZdjdZd ZdkdZd Zd Zdld Zd! Zd" Zd# Zd$ Zd% Zd& Z d' Z!d( Z"d) Z#dmd+Z$dmd,Z%d- Z&dnd.Z'dod0Z(dpd1Z)djd2Z*dpd3Z+dqd4Z,drd6Z-d7 Z.dsd8Z/dsd9Z0dsd:Z1dtd<Z2dsd=Z3dsd>Z4dsd?Z5d@ Z6dA Z7dB Z8dsdCZ9dsdDZ:dsdEZ;dF Z<dG Z=dH Z>dsdIZ?dJ Z@dK ZAdL ZBdM ZCdN ZDdO ZEdP ZdQ ZFdsdRZGdS ZHdT ZIdU ZJdsdVZKdW ZLdX ZMdY ZNdudZZOdvd[ZPd\ ZQd] ZRd^ ZSdwd`ZTdndaZUdb ZVdc ZWdxdeZXdf ZYdg ZZdS )yMongoHandlerc                 &   	 t          t          d          | _        | j                                         | j        t                   | _        | j        j        | _        | j        j        | _	        | j        j
        | _        | j        j        | _        t                              d           d S # t           j        j        t           j        j        f$ r>}t                              dt+          |                      t-          d          d }~ww xY w)Ni  )serverSelectionTimeoutMSz!Successfully connected to MongoDBzFailed to connect to MongoDB: zDCould not connect to MongoDB. Please check your connection settings.)r   r   clientserver_infor   db
test_cases
collection	analyticsanalytics_collectionuser_sessionsuser_sessions_collectionusersusers_collectionloggerinfopymongoerrorsConnectionFailureServerSelectionTimeoutErrorerrorstr	Exception)selfes     @/var/www/html/testcasegenerator.evdpl.com/utils/mongo_handler.py__init__zMongoHandler.__init__   s    	d%kDQQQDKK##%%%k*-DG"g0DO(,(9D%,0G,AD)$(GMD!KK;<<<<<0'.2\] 	d 	d 	dLLB#a&&BBCCCbccc	ds   B)B- -%D9DDuserc           	         	 | j                             d|                                i          }|rdddS t          j                    }t          j        |                    d          |          }t          t          j	                              |                                |||t          j                    ddd}| j                             |           t                              d	| d
|            dd|d         |d         |d         |d         ddS # t          $ r9}	t                              dt          |	                      dddcY d}	~	S d}	~	ww xY w)zCreate a new user accountemailF#User with this email already existssuccessmessageutf-8NT)_idr-   passwordnamerole
created_at
last_login	is_activezSuccessfully created user: z with role: User created successfullyr3   r5   r6   idr-   r5   r6   )r0   r1   r+   zError creating user: Failed to create user)r   find_onelowerbcryptgensalthashpwencoder%   uuiduuid4r   utcnow
insert_oner   r   r&   r$   )
r'   r-   r4   r5   r6   existing_usersalthashed_passworduser_docr(   s
             r)   create_userzMongoHandler.create_user&   s   %	J 1::GU[[]];STTM \#(5Z[[[ >##D$mHOOG,D,DdKKO 4:<<((+&o//"!	 	H !,,X666KKOeOOOOPPP6"5/%g.$V,$V,	 	 	 	  	J 	J 	JLL9Q99:::$1HIIIIIIII	Js#   4D C#D 
E%.EEEc                 `   	 | j                             ddi          }|rdddS |                     |||d          }|d         r"t                              d|            d	d
dS |S # t
          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)z:Create the initial admin user (should only be called once)r6   adminFzAdmin user already existsr/   )r6   r0   z!Successfully created admin user: TzAdmin user created successfullyzError creating admin user: Failed to create admin userN)r   r>   rL   r   r   r&   r$   r%   )r'   r-   r4   r5   existing_adminresultr(   s          r)   create_admin_userzMongoHandler.create_admin_userO   s    	P!2;;VW<MNNN R#(5PQQQ %%eXt'%JJFi  GGGHHH#'4UVVV 	P 	P 	PLL?s1vv??@@@$1NOOOOOOOO	Ps)   "A* AA* (A* *
B-4.B("B-(B-c           	         	 | j                             d|                                i          }|sdddS |                    dd          sdddS t	          j        |                    d          |d	                   r| j                             d
|d
         iddt          j	                    ii           | 
                    |d
                   }t                              d|            dd|d
         |d         |d         |                    dd          d|dS dddS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)zAuthenticate user loginr-   FzInvalid email or passwordr/   r9   TzAccount is deactivatedr2   r4   r3   $setr8   z!Successfully authenticated user: zLogin successfulr5   r6   r+   r;   )r0   r1   r+   tokenzError authenticating user: zAuthentication failedN)r   r>   r?   getr@   checkpwrC   
update_oner   rF   generate_jwt_tokenr   r   r&   r$   r%   )r'   r-   r4   r+   rU   r(   s         r)   authenticate_userzMongoHandler.authenticate_userc   s   &	J(117EKKMM2JKKD R#(5PQQQ 88K.. O#(5MNNN ~hoog66Z8HII R%00DK(lHO,=,=>?   //U<<GGGHHH#1"5k!%g $V $ 8 8	  #
 
 
 $)5PQQQ 	J 	J 	JLL?s1vv??@@@$1HIIIIIIII	Js/   4D' D' CD' "D' '
E*1.E%E*%E*c                 &   	 | j                             d|i          }|r/|                    dd          r|                    d          dk    S dS # t          $ r5}t                              dt          |                      Y d}~dS d}~ww xY w)	zCheck if a user is an adminr3   r9   Tr6   rN   FzError checking admin status: Nr   r>   rV   r&   r   r$   r%   r'   user_idr+   r(   s       r)   is_adminzMongoHandler.is_admin   s    	(115'2BCCD 3d33 3xx''7225 	 	 	LLAQAABBB55555	s   AA 
B*BBc                 
   	 |                      |          sdddS t          | j                            i ddddddddd                    }|D ]j}d|v rt	          |d                   |d<   d|v r|d                                         |d<   d|v r'|d         r|d                                         nd	|d<   kd
|dS # t          $ r9}t                              dt	          |                      dddcY d	}~S d	}~ww xY w)zGet all users (admin only)F)Access denied. Admin privileges required.r/      r3   r-   r5   r6   statusr7   r8   r9   r3   r7   r8   NT)r0   r   zError getting all users: Failed to retrieve users)	r_   listr   findr%   	isoformatr&   r   r$   )r'   admin_user_idr   r+   r(   s        r)   get_all_userszMongoHandler.get_all_users   ss   	M==// b#(5`aaa.33B
9 
9 
 
 
 
E  h hD=="%d5k"2"2DK4'')-l);)E)E)G)GD&4''KOP\K])gl);)E)E)G)G)GcgD&#e444 	M 	M 	MLL=SVV==>>>$1KLLLLLLLL	Ms#   B? B"B? ?
D	.C=7D=Dc                    	 |                      |          sdddS |dvrdddS | j                            d|idd|ii          }|j        d	k    r(t                              d
| d|            dd
| dS dddS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)zUpdate user role (admin only)Fra   r/   rN   r+   'Invalid role. Must be 'admin' or 'user'r3   rT   r6   r   User role updated to 
 by admin Tz User not found or role unchangedzError updating user role: zFailed to update user roleN	r_   r   rX   modified_countr   r   r&   r$   r%   )r'   ri   target_user_idnew_rolerQ   r(   s         r)   update_user_rolezMongoHandler.update_user_role   s3   	O==// b#(5`aaa 000#(5^___ *55'&(+, F
 $q((WHWWWWXXX#'4VH4V4VWWW#(5WXXX 	O 	O 	OLL>c!ff>>???$1MNNNNNNNN	Os.   A> A> AA> 9A> >
C.B<6C<Cc                    	 |                      |          sdddS | j                            d|idd|ii          }|j        dk    r/|rdnd	}t                              d
| d|            dd
| ddS dddS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)z&Toggle user active status (admin only)Fra   r/   r3   rT   r9   r   	activateddeactivatedzUser ro   Tz successfullyz"User not found or status unchangedzError toggling user status: zFailed to update user statusNrp   )r'   ri   rr   r9   rQ   status_textr(   s          r)   toggle_user_statuszMongoHandler.toggle_user_status   s'   	Q==// b#(5`aaa *55'+y12 F
 $q((-6IkkMJKJJ=JJKKK#'4VK4V4V4VWWW#(5YZZZ 	Q 	Q 	QLL@A@@AAA$1OPPPPPPPP	Qs)   A< AA< 7A< <
B?.B:4B?:B?c                 ^   	 |                      |          sdddS |                     ||||          }|d         r+t                              d| d| d|            dd	| dS |S # t          $ r9}t                              d
t          |                      dddcY d}~S d}~ww xY w)z"Create a new user account by adminFra   r/   r0   zUser created by admin : z with role Tz$User created successfully with role Error creating user by admin: r=   N)r_   rL   r   r   r&   r$   r%   )r'   ri   r-   r4   r5   r6   rQ   r(   s           r)   create_user_by_adminz!MongoHandler.create_user_by_admin   s    	J==// b#(5`aaa %%eXtTBBFi  ^]^^e^^X\^^___#'4a[_4a4abbb 	J 	J 	JLLB#a&&BBCCC$1HIIIIIIII	Js)   A) A
A) 'A) )
B,3.B'!B,'B,c                 |   	 |                      |          sdddS ||k    rdddS | j                            d|i          }|j        dk    r%t                              d| d|            d	d
dS dddS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)zDelete a user (admin only)Fra   r/   zCannot delete your own accountr3   r   zUser deleted by admin r{   TzUser deleted successfullyUser not foundzError deleting user: zFailed to delete userN)	r_   r   
delete_onedeleted_countr   r   r&   r$   r%   )r'   ri   rr   rQ   r(   s        r)   delete_userzMongoHandler.delete_user   s   	J==// b#(5`aaa ..#(5UVVV *55un6MNNF#a''V]VVnVVWWW#'4OPPP#(5EFFF 	J 	J 	JLL9Q99:::$1HIIIIIIII	Js.   A8 
A8 AA8 3A8 8
B;.B60B;6B;c                 \   	 |                      |          sdddS | j                            i           }| j                            ddi          }| j                            ddi          }| j                            ddi          }d	d
lm}m}  |j                                        dd	d	d	d	          }| j                            dd|ii          }	||||z
  |||	d}
d|
dS # t          $ r9}t          	                    dt          |                      dddcY d}~S d}~ww xY w)z Get user statistics (admin only)Fra   r/   r9   Tr6   rN   r+   r   r
   rb   dayhourminutesecondmicrosecondr7   $gte)total_usersactive_usersinactive_usersadmin_usersregular_usersnew_users_this_month)r0   
statisticszError getting user statistics: z"Failed to retrieve user statisticsN)r_   r   count_documentsr   r   rF   replacer&   r   r$   r%   )r'   ri   r   r   r   r   r   r   	first_dayr   statsr(   s               r)   get_user_statisticsz MongoHandler.get_user_statistics  s   !	W==// b#(5`aaa /??CCK  0@@+tATUUL /??@QRRK 1AA66BRSSM 54444444'))11aaRSab1ccI#'#8#H#H,Y_ajXkIl#m#m   + ,"-"<*!.(< E  $5999 	W 	W 	WLLC3q66CCDDD$1UVVVVVVVV	Ws#   C( CC( (
D+2.D& D+&D+c                    	 | j                             d|iddi          }|rmd|v rt          |d                   |d<   d|v r|d                                         |d<   d|v r'|d         r|d                                         nd|d<   d|dS d	d
dS # t          $ r9}t
                              dt          |                      d	ddcY d}~S d}~ww xY w)zGet user details by IDr3   r4   r   r7   r8   NTr0   r+   Fr   r/   zError getting user by ID: zFailed to retrieve user)r   r>   r%   rh   r&   r   r$   r]   s       r)   get_user_by_idzMongoHandler.get_user_by_id=  s7   	L(115'2BAE  D  GD=="%d5k"2"2DK4'')-l);)E)E)G)GD&4''KOP\K])gl);)E)E)G)G)GcgD&#'666#(5EFFF 	L 	L 	LLL>c!ff>>???$1JKKKKKKKK	Ls$   BB B 
C.CCCc                 ~   	 | j                             d|i          }|sdddS |                    d          dk    r||k    rdddS dd	g|                    d          dk    r                    dd	g           fd
|                                D             }|sdddS | j                             d|id|i          }|j        dk    r%t                              d| d|            dddS dddS # t          $ r9}t          
                    dt          |                      dddcY d}~S d}~ww xY w)zYUpdate user profile (admin can update any user, regular users can only update themselves)r3   FzCurrent user not foundr/   r6   rN   z4Access denied. You can only update your own profile.r5   r-   c                 $    i | ]\  }}|v 	||S  r   ).0kvallowed_fieldss      r)   
<dictcomp>z4MongoHandler.update_user_profile.<locals>.<dictcomp>g  s)    XXXAADWDW1DWDWDW    zNo valid fields to updaterT   r   zUser profile updated by r{   TzProfile updated successfullyzNo changes madezError updating user profile: zFailed to update profileN)r   r>   rV   extenditemsrX   rq   r   r   r&   r$   r%   )	r'   current_user_idrr   updatescurrent_userfiltered_updatesrQ   r(   r   s	           @r)   update_user_profilez MongoHandler.update_user_profileU  s   #	M0995/:RSSL O#(5MNNN ''722.7X7X#(5klll %g.N''722%%vw&7888  YXXXXXX# R#(5PQQQ *55')* F
 $q((ZZZ.ZZ[[[#'4RSSS#(5FGGG 	M 	M 	MLLAQAABBB$1KLLLLLLLL	Ms6   "C9 #C9 
AC9 %AC9 4C9 9
D<.D71D<7D<c                 X   	 | j                             d|i          }|sdddS t          j        |                    d          |d                   sdddS t          j                    }t          j        |                    d          |          }| j                             d|idd|ii          }|j        d	k    r"t          
                    d
|            dddS dddS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)zChange user passwordr3   Fr   r/   r2   r4   zCurrent password is incorrectrT   r   zPassword changed for user: TzPassword changed successfullyzFailed to update passwordzError changing password: zFailed to change passwordN)r   r>   r@   rW   rC   rA   rB   rX   rq   r   r   r&   r$   r%   )	r'   r^   current_passwordnew_passwordr+   rI   hashed_new_passwordrQ   r(   s	            r)   change_passwordzMongoHandler.change_password|  s   	N(115'2BCCD G#(5EFFF >"2"9"9'"B"BDDTUU V#(5TUUU >##D"(-0C0CG0L0Ld"S"S *55 *&9:; F
 $q((C'CCDDD#'4STTT#(5PQQQ 	N 	N 	NLL=SVV==>>>$1LMMMMMMMM	Ns/   "C& 2C& BC& !C& &
D)0.D$D)$D)c                    	 |                      |          sdddS t          j                    }t          j        |                    d          |          }| j                            d|idd|ii          }|j        dk    r%t          	                    d	| d
|            dddS dddS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)zReset user password by adminFra   r/   r2   r3   rT   r4   r   zPassword reset by admin z for user: TPassword reset successfullyr   z#Error resetting password by admin: Failed to reset passwordN)r_   r@   rA   rB   rC   r   rX   rq   r   r   r&   r$   r%   )r'   ri   rr   r   rI   r   rQ   r(   s           r)   reset_password_by_adminz$MongoHandler.reset_password_by_admin  s?   	M==// b#(5`aaa >##D"(-0C0CG0L0Ld"S"S *55'*&9:; F
 $q((a}aaQ_aabbb#'4QRRR#(5EFFF 	M 	M 	MLLGs1vvGGHHH$1KLLLLLLLL	Ms)   B- BB- (B- -
C07.C+%C0+C0c                 @   	 ddl }ddl}ddlm}m} |                    d          } |j        |                                                                          } |j                     |d          z   }||| |j                    dd}	| j	        j
                            |	          }
|
j        r#t                              d	|            d
||dS dddS # t          $ r9}t                              dt#          |                      dddcY d}~S d}~ww xY w)z1Create a password reset token for the given emailr   Nr
       rb   hoursF)r-   
token_hash
expires_atr7   usedz(Password reset token created for email: T)r0   rU   r   zFailed to create reset tokenr/   z%Error creating password reset token: )secretshashlibr   r   token_urlsafesha256rC   	hexdigestrF   r   password_reset_tokensrG   inserted_idr   r   r&   r$   r%   )r'   r-   r   r   r   r   rU   r   r   
reset_datarQ   r(   s               r)   create_password_reset_tokenz(MongoHandler.create_password_reset_token  sx    	QNNNNNN44444444 ))"--E'77AACCJ )**YYQ-?-?-??J ((-ho// J W2==jIIF! UNuNNOOO#'%zRRR#(5STTT 	Q 	Q 	QLLIQIIJJJ$1OPPPPPPPP	Qs$   CC C 
D$.DDDc                    	 ddl }ddlm}  |j        |                                                                          }| j        j                            |dd |j                    id          }|rd|d         d	S dd
dS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)z<Verify a password reset token and return user email if validr   Nr   F$gtr   r   r   Tr-   )r0   r-   Invalid or expired reset tokenr/   z&Error verifying password reset token: zFailed to verify reset token)r   r   r   rC   r   r   r   r>   rF   r&   r   r$   r%   )r'   rU   r   r   r   reset_recordr(   s          r)   verify_password_reset_tokenz(MongoHandler.verify_password_reset_token  s   	QNNN)))))) (77AACCJ  78AA($oho&7&78C C  L  W#',w2GHHH#(5UVVV 	Q 	Q 	QLLJ#a&&JJKKK$1OPPPPPPPP	Qs$   A<B ?B 
C.C<CCc                    	 ddl }ddlm}  |j        |                                                                          }| j        j                            |dd |j                    id          }|sdddS |d	         }t          j
                    }t          j        |                    d
          |          }	| j                            d	|idd|	ii          }
|
j        dk    r\| j        j                            d|d         idd |j                    di           t                              d|            dddS dddS # t"          $ r9}t                              dt'          |                      dddcY d}~S d}~ww xY w)z-Use a password reset token to change passwordr   Nr   Fr   r   r   r/   r-   r2   rT   r4   r3   T)r   used_atz'Password reset successfully for email: r   r   z"Error using password reset token: r   )r   r   r   rC   r   r   r   r>   rF   r@   rA   rB   r   rX   rq   r   r   r&   r$   r%   )r'   rU   r   r   r   r   r   r-   rI   r   user_resultr(   s               r)   use_password_reset_tokenz%MongoHandler.use_password_reset_token  s   +	MNNN)))))) (77AACCJ  78AA($oho&7&78C C  L   W#(5UVVV )E >##D"(-0C0CG0L0Ld"S"S /::% *&9:; K
 )A---88L/0dx7H7HIIJ  
 MeMMNNN#'4QRRR#(5EFFF 	M 	M 	MLLFc!ffFFGGG$1KLLLLLLLL	Ms+   A6E	 9C
E	 E	 	
F.FFF   c                 ^   	 |                      |          sdddS dd|ddid|ddigi}t          | j                            |d	d
i                              |                    }|D ]j}d|v rt          |d                   |d<   d|v r|d                                         |d<   d|v r'|d         r|d                                         nd|d<   kd|t          |          dS # t          $ r9}t          
                    dt          |                      dddcY d}~S d}~ww xY w)z*Search users by name or email (admin only)Fra   r/   z$orr5   i)z$regexz$optionsr-   r4   r   r3   r7   r8   NT)r0   r   countzError searching users: zFailed to search users)r_   rf   r   rg   limitr%   rh   lenr&   r   r$   )r'   ri   queryr   search_queryr   r+   r(   s           r)   search_userszMongoHandler.search_users"  s   	K==// b#(5`aaa 3??@C@@AL .33LAC  uU|| E
  h hD=="%d5k"2"2DK4'')-l);)E)E)G)GD&4''KOP\K])gl);)E)E)G)G)GcgD&#ec%jjIII 	K 	K 	KLL;3q66;;<<<$1IJJJJJJJJ	Ks#   C) CC) )
D,3.D'!D,'D,N2   c           
      (   	 |                      |          sdddS i }|r||d<   t          | j                            |ddddd                              dd                              |                    }|D ]?}d	|v rt          |d	                   |d	<   d|v r|d                                         |d<   @d
|t          |          dS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)z#Get user activity logs (admin only)Fra   r/   r^   rb   )r^   r7   source_typerd   r7   r3   T)r0   logsr   z"Error getting user activity logs: z Failed to retrieve activity logsN)r_   rf   r   rg   sortr   r%   rh   r   r&   r   r$   )r'   ri   r^   r   r   r   logr(   s           r)   get_user_activity_logsz#MongoHandler.get_user_activity_logsE  sk   	U==// b#(5`aaa E +#*i  ,,U 	5 5  
 tL"%%eeEll4 4D  F FC<<!$SZCJ3&&(+L(9(C(C(E(EC%#TCIIFFF 	U 	U 	ULLFc!ffFFGGG$1STTTTTTTT	Us#   C B1C 
D.DDDc           	         	 |                      |          sdddS t          |t                    sdddS d}g }|D ]}|                    d          }|                    d          }|r|s|                    d|            I|d	vr|                    d
| d|            i| j                            d|idd|ii          }|j        dk    r)|dz  }t          	                    d| d| d|            |                    d|            dd| d||dS # t          $ r9}	t                              dt          |	                      dddcY d}	~	S d}	~	ww xY w)z#Bulk update user roles (admin only)Fra   r/   z.Invalid format. Expected list of user updates.r   r^   r6   z$Missing user_id or role for update: rl   zInvalid role 'z' for user r3   rT   rb   rn   ro   r{   zFailed to update role for user TzBulk update completed. z users updated.)r0   r1   updated_countr!   z!Error in bulk update user roles: zFailed to perform bulk updateN)r_   
isinstancerf   rV   appendr   rX   rq   r   r   r&   r$   r%   )
r'   ri   user_updatesr   r!   updater^   rs   rQ   r(   s
             r)   bulk_update_user_rolesz#MongoHandler.bulk_update_user_rolesf  s   -	R==// b#(5`aaa lD11 g#(5efffMF& O O **Y//!::f-- h MM"Q"Q"QRRR#444MM"Q8"Q"Q"Q"QRRR .99G$fh/0 
 (1,,!Q&MKK f f fM f f]d f fggggMM"MG"M"MNNNN  S]SSS!. 	    	R 	R 	RLLESVVEEFFF$1PQQQQQQQQ	Rs(   D D C'D 
E!(.EE!E!jsonc                 l   	 |                      |          sdddS t          | j                            i ddi                    }|D ]j}d|v rt	          |d                   |d<   d|v r|d                                         |d<   d|v r'|d         r|d                                         nd	|d<   k|d
k    rd|d
dS |dk    rdd	l}dd	l}|                                }|rZ|d         	                                }|
                    ||          }	|	                                 |	                    |           |                                }
|                                 d|
ddS dddS # t          $ r9}t                               dt	          |                      dddcY d	}~S d	}~ww xY w)zExport user data (admin only)Fra   r/   r4   r   r3   r7   r8   Nr   T)r0   dataformatcsv)
fieldnameszUnsupported format typezError exporting user data: zFailed to export user data)r_   rf   r   rg   r%   rh   r   ioStringIOkeys
DictWriterwriteheader	writerowsgetvaluecloser&   r   r$   )r'   ri   format_typer   r+   r   r   outputr   writercsv_datar(   s               r)   export_user_datazMongoHandler.export_user_data  s#   *	O==// b#(5`aaa .33BA9    E
  h hD=="%d5k"2"2DK4'')-l);)E)E)G)GD&4''KOP\K])gl);)E)E)G)G)GcgD&f$$#'&III%%


			 ,!&qJ ^^Fz^JJF&&((($$U+++!??,,#'UKKK#(5NOOO 	O 	O 	OLL?s1vv??@@@$1MNNNNNNNN	Os0   E0 B"E0 ?B+E0 +E0 0
F3:.F.(F3.F3c                    	 | j                             d|i          }|sdddS t          | j                            d|idddddd                              dd	                              d
                    }|D ]?}d|v rt          |d                   |d<   d|v r|d                                         |d<   @| j        	                    d|i          }ddl
m
}m}  |j                                        ddddd          }| j        	                    |d|id          }	| j                            d|idddd          }
|
r=d|
v rt          |
d                   |
d<   d|
v r|
d                                         |
d<   |d         |d         |d         |                    dd          |                    d          r|d                                         nd|                    d          r|d                                         ndd||	|
d|d}|                    d          dk    rR|                     |          }|d         r|d         |d<   |                     |d
          }|d         r|d         |d <   d!|d"S # t"          $ r9}t$                              d#t          |                      dd$dcY d}~S d}~ww xY w)%.Get user dashboard data with role-based accessr3   Fr   r/   r^   rb   r3   titler7   r   rd   r7   r   
   r   r
   r   r   r^   r7   )r3   r   r7   r5   r-   r6   r+   Nr8   r<   r5   r-   r6   r7   r8   total_test_cases
this_monthlast_generated)	user_infor   recent_test_casesrN   r0   r   admin_statistics)r   r   recent_activityTr0   dashboard_data#Error getting user dashboard data: !Failed to retrieve dashboard data)r   r>   rf   r   rg   r   r   r%   rh   r   r   r   rF   r   rV   r   r   r&   r   r$   )r'   r^   r+   user_test_cases	test_caser  r   r   r   this_month_countr  r	  admin_statsr  r(   s                  r)   get_user_dashboard_dataz$MongoHandler.get_user_dashboard_data  s   I	V(115'2BCCD G#(5EFFF #4?#7#7G$AQqTUVV$ $ d<$$UU2YY0 0O - R R	I%%'*9U+;'<'<Ie$9,,.7.E.O.O.Q.QIl+  $>>	7?STT 54444444'))11aaRSab1ccI#>>"%y1@ @     "_55G$AQ77 N
  \N**,/u0E,F,FN5)>113A,3O3Y3Y3[3[N<0 u+ L!'] HHVV44DHHH\DZDZ"d$|"4">">"@"@"@`dDHHH\DZDZ"d$|"4">">"@"@"@`d  )9"2&4 
 &5 N$ xx7**"66w??y) S9D\9RN#56 #'"="=gR"="P"P"9- P8G8ON#45#~FFF 	V 	V 	VLLGs1vvGGHHH$1TUUUUUUUU	Vs#   "J I'J 
K.KKKc                 0   	 |                      |          sdddS | j                            i           }| j                            i           }| j                            i           }t          | j                            i dddddd                              dd                              d                    }|D ]?}d	|v rt          |d	                   |d	<   d|v r|d         
                                |d<   @|                     |          }|d
z  |dz  |dz  d}|||||d         r|                    di           ni |dd}	d|	dS # t          $ r9}
t                              dt          |
                      dddcY d}
~
S d}
~
ww xY w)z Get system overview (admin only)Fra   r/   rb   )r3   r   r7   r^   r   r7   r   r   r3   i   i   i   )test_cases_size
users_sizeanalytics_sizer0   r   healthy)r  r   total_analyticsr  user_statisticsstorage_infosystem_healthT)r0   system_overviewzError getting system overview: z"Failed to retrieve system overviewN)r_   r   r   r   r   rf   rg   r   r   r%   rh   r   rV   r&   r   r$   )r'   ri   r  r   r  r  r  
user_statsr  r  r(   s              r)   get_system_overviewz MongoHandler.get_system_overview  s   2	W==// b#(5`aaa  $>>rBB/??CCK"7GGKKO !%T_%9%9" ? ? & & tL"%%eeBii!1 !1 / R R	I%%'*9U+;'<'<Ie$9,,.7.E.O.O.Q.QIl+ 11-@@J $4d#:)C/"1D"8 L %5*#2#4GQR[G\#d:>>,#C#C#Cbd ,!* O  $HHH 	W 	W 	WLLC3q66CCDDD$1UVVVVVVVV	Ws#   E D5E 
F.F
FFrb   r   c                    	 |                      |          sdddS |dz
  |z  }| j                            i           }t          | j                            i ddddddddd                              dd                              |                              |                    }|D ]}d|v rt          |d                   |d<   	 d	d
l	m	} d|v r3t          |d         |          r|d                                         |d<   d|v rE|d         t          |d         |          r'|d         r|d                                         nd|d<   # t          $ r Y w xY w||z   dz
  |z  }	d|||||	||	k     |dk    ddS # t          $ r9}
t                              dt          |
                      dddcY d}
~
S d}
~
ww xY w)z*Get all users with pagination (admin only)Fra   r/   rb   rc   r7   r   r3   r   r   r8   NT)current_pageper_pager   total_pageshas_nexthas_prev)r0   r   
paginationzError getting paginated users: re   )r_   r   r   rf   rg   r   skipr   r%   r   r   rh   r&   r   r$   )r'   ri   pager  r$  r   r   r+   _dtr   r(   s              r)   get_all_users_paginatedz$MongoHandler.get_all_users_paginatedH  st   :	M==// b#(5`aaa 1H(D /??CCK .33B
9 
9 
 
 tL"%%dd4jjx
B 
BE   D=="%d5k"2"2DK888888#t++
4;Ms0S0S+-1,-?-I-I-K-K\*#t++l1C1KzZ^_kZlnqOrOr1KOST`Oa-kT,-?-I-I-K-K-Kgk\*    D
 '1A5(BK  $( (#.#. ${ 2 $q     	M 	M 	MLLC3q66CCDDD$1KLLLLLLLL	MsH   F B-F 
BEF 
EF E"F 
G.F?9G?Gc                    	 |                      |          sdddS d}	 | j                            d           n# t          $ r d}Y nw xY wi }g d}|D ]u}	 |dk    r| j        }n|d	k    r| j        }n|d
k    r| j        }|                    i           }d|d||<   J# t          $ r}dt          |          d||<   Y d}~nd}~ww xY wddl	m	}	m
}
  |	j                     |
d          z
  }| j                            dd|ii          | j                            dd|ii          | j                            dd|ii          d}d}|dk    rd}n-t          d |                                D                       rd}d|||| |	j                                                    ddS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)%Get system health status (admin only)Fra   r/   r  ping	unhealthy)r   r   r   r   r   r   rd   document_count)rd   r$   Nr   r
   rb   daysr7   r   r8   )new_users_24hnew_test_cases_24hactive_users_24hcriticalc              3   .   K   | ]}|d          dk    V  dS )rd   r+  Nr   )r   cols     r)   	<genexpr>z1MongoHandler.get_system_health.<locals>.<genexpr>  s+      YYcS]k1YYYYYYr   warningT)overall_statusdatabase_statuscollections_statusr  	timestamp)r0   r  zError getting system health: z Failed to retrieve system health)r_   r   commandr&   r   r   r   r   r%   r   r   nowanyvaluesrh   r   r$   )r'   ri   	db_statusr:  collectionscollection_namer   r   r(   r   r   	yesterdayr  overall_healths                 r)   get_system_healthzMongoHandler.get_system_health  s   C	U==// b#(5`aaa "I('''' ( ( ('			( "$>>>K#.  &'11%)%:

(L88%)_

(K77%)%>
 '66r::E"+*/; ;&77 !   "-!$Q; ;&777777 54444444$):):)::I "&!6!F!FW]_hViGj!k!k&*o&E&E|V\^gUhFi&j&j$($9$I$I<Z`bkYlJm$n$n O 'NK''!+YY=O=V=V=X=XYYYYY +!*  &4'0*<'6!-!9!9!;!;" "	 	 	  	U 	U 	ULLAQAABBB$1STTTTTTTT	Usn   F* F* : F* A	F* A		F* ABF* 
C(C=F* CC"F* *
G-4.G("G-(G-c           
      J   	 |                      |          sdddS ddlm}m} | j                            i           }| j                            ddi          }| j                            ddi          }| j                            d	d
i          } |j                     |d          z
  }| j                            dd|ii          }	ddddiddididdddddiddidddd ddd!id"d#d$iig}
t          | j                            |
                    }|D ][}d|v rt          |d                   |d<   d%|v rt          |d%                   |d%<   d&|v r|d&         
                                |d&<   \dd'ddid(ig}t          | j                            |                    }d
|||||	d)|d*d+         | |j                    
                                d,d-S # t          $ r9}t                              d.t          |                      dd/dcY d*}~S d*}~ww xY w)0z(Get detailed user analytics (admin only)Fra   r/   r   r
   r6   rN   r+   r9   T   r.  r7   r   $group$user_id$sumrb   $max$created_at)r3   test_case_countlast_activityz$lookupr   r3   r  )from
localFieldforeignFieldas$unwindz
$user_info$project$_idz$user_info.namez$user_info.email)r^   	user_name
user_emailrM  rN  $sortrM  r   r^   rN  $source_typer3   r   )r   r   r   r   users_created_30dNr   )r  user_activitysource_distributiongenerated_at)r0   r   z'Error getting detailed user analytics: z!Failed to retrieve user analytics)r_   r   r   r   r   r=  rf   r   	aggregater%   rh   r&   r   r$   )r'   ri   r   r   r   r   r   r   thirty_days_agor[  pipeliner\  activitysource_pipeliner]  r(   s                   r)   get_detailed_user_analyticsz(MongoHandler.get_detailed_user_analytics  s&   \	V==// b#(5`aaa44444444 /??CCK/??@QRRK 1AA66BRSSM0@@+tATUUL +hlnnyyb/A/A/AAO $ 5 E E|V\^mUnFo p p
 ),2A;*0-)@   '&+(-)	    | #)%6&8+,)*! ! /49HB !!:!:8!D!DEEM * V VH$$&)(5/&:&:HUO((*-hy.A*B*BHY'"h..080I0S0S0U0UH_-
 -"(! O #'t'@'@'Q'Q"R"R   (3'2)6(4->( ( &33B3%7+>$0HLNN$<$<$>$>      	V 	V 	VLLK3q66KKLLL$1TUUUUUUUU	Vs#   G GG 
H").HH"H"c           	         	 |                      |          sdddS g d}|D ]}||vs||         s
dd| dc S | j                            d|d         i          }|rdddS |                     |d                   }|d	         |d         ||                    d
d          |                    dd          t          j                    ddd}| j                            |          }|j        rddt          |j                  dS dddS # t          $ r9}	t                              dt          |	                      dddcY d}	~	S d}	~	ww xY w)z'Create a new user by admin (admin only)Fra   r/   )r5   r-   r4   zMissing required field: r-   r.   r4   r5   r6   r+   r9   TNactive)r5   r-   r4   r6   r9   r7   r8   rd   r:   )r0   r1   r^   r=   r|   )r_   r   r>   hash_passwordrV   r   r=  rG   r   r%   r&   r   r$   )
r'   ri   	user_datarequired_fieldsfieldrH   rJ   rK   rQ   r(   s
             r)   r}   z!MongoHandler.create_user_by_admin-  s   -	J==// b#(5`aaa <;;O( ] ]	))51A)',9[TY9[9[\\\\\ * !1::GYwEW;XYYM \#(5Z[[[ #00:1FGGO "&)"7++!ff55&]];==&lnn""	 	H *55h??F! N#:"6#566   $)5LMMM 	J 	J 	JLLB#a&&BBCCC$1HIIIIIIII	Js4   D D )D $B#D D 
E.EEEc           	      X   	 |                      |          sdddS ddlm} t          | j                            i ddi                    }|D ]j}d|v rt          |d                   |d<   d|v r|d                                         |d<   d	|v r'|d	         r|d	                                         nd
|d	<   kt          | j                            i                     }|D ]?}d|v rt          |d                   |d<   d|v r|d                                         |d<   @t          | j                            i                     }|D ]?}d|v rt          |d                   |d<   d|v r|d                                         |d<   @ |j	                                                    |dd|||t          |          t          |          t          |          dd}	d|	dS # t          $ r9}
t                              dt          |
                      dddcY d
}
~
S d
}
~
ww xY w)zExport system data (admin only)Fra   r/   r   r   r4   r3   r7   r8   Nr;  z1.0)exported_atexported_byversion)r   r  r  )export_infor   r   r   r   T)r0   r   zError exporting system data: zFailed to export system data)r_   r   rf   r   rg   r%   rh   r   r   r=  r   r&   r   r$   )r'   ri   r   r   r+   r   r  r   analyticexport_datar(   s              r)   export_system_datazMongoHandler.export_system_data^  s   5	Q==// b#(5`aaa)))))) .33BQHHIIE h hD=="%d5k"2"2DK4'')-l);)E)E)G)GD&4''KOP\K])gl);)E)E)G)G)GcgD& do2226677J' R R	I%%'*9U+;'<'<Ie$9,,.7.E.O.O.Q.QIl+ T6;;B??@@I% N NH$$&)(5/&:&:HUO(**,4[,A,K,K,M,MH[) $08<>>#;#;#=#=#0$   
 (&#&u::(+J'*9~~  K   $[999 	Q 	Q 	QLLAQAABBB$1OPPPPPPPP	Qs#   G& G	G& &
H)0.H$H)$H)c                    	 |                      |          sdddS t          j                                                    ddddt          j                    t	          d	          z
                                  dd
ddt          j                    t	          d	          z
                                  ddddt          j                    t	          d	          z
                                  ddddg}d|dS # t
          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)zGet system logs (admin only)Fra   r/   r   zSystem started successfullySystem)r;  levelr1   sourcerb   r   zUser authentication successfulAuth   r7  High memory usage detected   r$   zDatabase connection timeoutDatabaseT)r0   r   zError getting system logs: zFailed to retrieve system logsN)	r_   r   r=  rh   r   r&   r   r$   r%   )r'   ri   	mock_logsr(   s       r)   get_system_logszMongoHandler.get_system_logs  s}   %	S==// b#(5`aaa
 "*!9!9!;!;#<&	  #+,..913E3E3E"E!P!P!R!R#?$	  #+,..913E3E3E"E!P!P!R!R&;&	  #+,..913E3E3E"E!P!P!R!R$<(	 'I6  $Y777 	S 	S 	SLL?s1vv??@@@$1QRRRRRRRR	S#   C: CC: :
D=.D82D=8D=c                    	 |                      |          sdddS ddlm}  |j                                                    |dd| j                            i           | j                            i           | j                            i           d}d	d
|dS # t          $ r9}t          
                    dt          |                      dddcY d}~S d}~ww xY w)z!Create system backup (admin only)Fra   r/   r   r   full)r7   
created_bybackup_type)backup_infousers_counttest_cases_countanalytics_countTz"System backup created successfully)r0   r1   r  zError creating system backup: zFailed to create system backupN)r_   r   r=  rh   r   r   r   r   r&   r   r$   r%   )r'   ri   r   backup_datar(   s        r)   create_system_backupz!MongoHandler.create_system_backup  s.   	S==// b#(5`aaa))))))
 #/(,..":":"<"<"/#)   
  $4DDRHH$(O$C$CB$G$G#'#<#L#LR#P#P	 	K  ?*    	S 	S 	SLLB#a&&BBCCC$1QRRRRRRRR	Ss#   B A=B 
C$.CCCc                    	 |                      |          sdddS t          t          t          t          t          t          d}|                                D ])\  }}||v r t	          ||         |          s
dd| dc S *dd|dS # t
          $ r9}t                              d	t          |                      dd
dcY d}~S d}~ww xY w)z#Update system settings (admin only)Fra   r/   )enableRegistrationrequireEmailVerificationmaxTestCasessessionTimeoutemailNotificationsadminAlertszInvalid setting type for Tz$System settings updated successfully)r0   r1   settingsz Error updating system settings: z Failed to update system settingsN)	r_   boolintr   r   r&   r   r$   r%   )r'   ri   r  valid_settingskey
value_typer(   s          r)   update_system_settingsz#MongoHandler.update_system_settings  s'   	U==// b#(5`aaa '+,0 #"%&*# N $2#7#7#9#9 \ \Z(??:hsmZ+P+P?',9ZUX9Z9Z[[[[[  A$    	U 	U 	ULLDCFFDDEEE$1STTTTTTTT	Us)   B A#B  B 
C
.C?C
C
c           	      D   	 |                      |          sdddS ddlm} g }	  ||          }|                    d|i           n# t          $ r Y nw xY w|                    d|i           ddddddddd}d	}|D ]!}| j                            ||          }|r n"|sdd
dS t          |d                   |d<   	 ddlm}	 d|v r3t          |d         |	          r|d         
                                |d<   d|v rE|d         t          |d         |	          r'|d         r|d         
                                nd	|d<   n# t          $ r Y nw xY wd|dS # t          $ r9}
t                              dt          |
                      dddcY d	}
~
S d	}
~
ww xY w)zGet user details (admin only)Fra   r/   r   r   r3   rb   rc   Nr   r   r7   r8   Tr   zError getting user details: zFailed to retrieve user details)r_   bsonr	   r   r&   r   r>   r%   r   r   rh   r   r$   )r'   ri   rr   r	   query_candidatesuser_object_id
projectionr+   qr&  r(   s              r)   get_user_detailszMongoHandler.get_user_details  s   7	T==// b#(5`aaa%%%%%%  "!).!9!9 ''(?@@@@    ##UN$;<<< 	 	J D%  ,55aDD E  G#(5EFFF d5k**DK4444444''JtL7I3,O,O')-l);)E)E)G)GD&4''T,-?-G:VZ[gVhjmKnKn-GKOP\K])gl);)E)E)G)G)GcgD&     $T222 	T 	T 	TLL@A@@AAA$1RSSSSSSSS	Tsq   E E "A E 
AE AAE 'E  BE E 
EE EE 
F&.FFFc                    	 |                      |          sdddS ddlm} g }	  ||          }|                    d|i           n# t          $ r Y nw xY w|                    d|i           d}d}|D ]"}	| j                            |	          }|r|	} n#|sdddS d	|v r|d	         sdd
dS d|v r|d         sdddS d|v rH|d         |                    d          k    r)| j                            d|d         i          }
|
rdddS d|v r|d         dvrdddS i }d	|v r|d	         |d	<   d|v r|d         |d<   d|v r|d         |d<   d|v rt          |d                   |d<   | j        	                    |d|i          }|j
        dk    rdddS dddS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)z!Update user by admin (admin only)Fra   r/   r   r   r3   Nr   r5   zName cannot be emptyr-   zEmail cannot be emptyzEmail already existsr6   rl   rm   r9   rT   TzUser updated successfullyzNo changes made to userzError updating user by admin: zFailed to update user)r_   r  r	   r   r&   r   r>   rV   r  rX   rq   r   r$   r%   )r'   ri   rr   rh  r	   r  r  rH   chosen_queryr  email_existsupdate_datarQ   r(   s                 r)   update_user_by_adminz!MongoHandler.update_user_by_admin?  s   D	J==// b#(5`aaa%%%%%%  "!).!9!9 ''(?@@@@   ##UN$;<<< !ML%   $ 5 > >q A A  #$LE ! G#(5EFFF ""9V+<"#(5KLLL)##Ig,>##(5LMMM )##	'(:m>O>OPW>X>X(X(X#4==w	RYHZ>[\\ Q',9OPPP ""y'8@Q'Q'Q#(5^___ K""&/&7F#)##'0'9G$""&/&7F#i''+/	+0F+G+GK( *55lV[DYZZF$q((#:  
 $)5NOOO 	J 	J 	JLLB#a&&BBCCC$1HIIIIIIII	Jsl   F F "A F 
AF AA	F F 0F AF F  A7F F 
G '.GG G r  c                 \   	 |                      |          sdddS i }|dv rt          | j                            i ddi                    }|D ]j}d|v rt	          |d                   |d<   d|v r|d                                         |d<   d	|v r'|d	         r|d	                                         nd
|d	<   k||d<   |dv rvt          | j                            i ddddddd                    }|D ]?}d|v rt	          |d                   |d<   d|v r|d                                         |d<   @||d<   |dv rtt          | j                            i ddddd                    }|D ]?}	d|	v rt	          |	d                   |	d<   d|	v r|	d                                         |	d<   @||d<   |t          j	                                                    |t          |                    dg                     t          |                    dg                     t          |                    dg                     d|d<   t                              d| d| d           d|dS # t          $ r9}
t                              dt	          |
                      dddcY d
}
~
S d
}
~
ww xY w)zBackup user data (admin only)Fra   r/   r  r   r4   r   r3   r7   r8   Nr   r  r   rb   )r3   r   r7   r^   r   rd   r   r  r   )r3   r7   typer   r   )r  r7   r  r   r  r  metadatazBackup created by admin r{   z backupT)r0   r  zError creating backup: zFailed to create backup)r_   rf   r   rg   r%   rh   r   r   r   rF   r   rV   r   r   r&   r$   )r'   ri   r  r  r   r+   r   r  r   rp  r(   s              r)   backup_user_datazMongoHandler.backup_user_data  s{   M	L==// b#(5`aaaK///T277=    
 " l lD}}&)$u+&6&6U#t++-1,-?-I-I-K-K\*#t++OST`Oa-kT,-?-I-I-K-K-Kgk\*',G$444!$/"6"6r"# #$< < # #  
 ", V VI	))+.y/?+@+@	%(#y002;L2I2S2S2U2U	,/,6L)333 !:!?!?"#	E E " "  	 !* T TH((*-huo*>*>#x//19,1G1Q1Q1S1S.+4K(  +&o//99;;+";??7B#?#?@@$'b(I(I$J$J#&{{B'G'G#H#H' 'K
# KKX=XXKXXXYYY#K@@@ 	L 	L 	LLL;3q66;;<<<$1JKKKKKKKK	Ls#   I( II( (
J+2.J& J+&J+c                 R   	 |                      |          sdddS t          |t                    rd|vrdddS d}g }|dv rd|v r	 |d         D ]}d	|v r%|d	         rt          j        |d	                   |d	<   d
|v r%|d
         rt          j        |d
                   |d
<   | j                            |          }|j        r|dz  }{|                    d|	                    dd                      n<# t          $ r/}|                    dt          |                      Y d}~nd}~ww xY w|dv rd|v r	 |d         D ]~}	d	|	v r%|	d	         rt          j        |	d	                   |	d	<   | j                            |	          }|j        r|dz  }R|                    d|		                    dd                      n<# t          $ r/}|                    dt          |                      Y d}~nd}~ww xY w|dv rd|v r	 |d         D ]g}
d	|
v r%|
d	         rt          j        |
d	                   |
d	<   | j                            |
          }|j        r|dz  }R|                    d           hn<# t          $ r/}|                    dt          |                      Y d}~nd}~ww xY wt                              d| d| d           dd| d||d S # t          $ r9}t                              d!t          |                      dd"dcY d}~S d}~ww xY w)#z*Restore user data from backup (admin only)Fra   r/   r  zInvalid backup data formatr   r  r   r7   r8   rb   zFailed to restore user: r-   UnknownzError restoring users: Nr  r   zFailed to restore test case: r   zError restoring test cases: r  r   zError restoring analytic datazError restoring analytics: z$Data restoration completed by admin r{   z restoreTzRestoration completed. z items restored.)r0   r1   restored_countr!   zError restoring data: zFailed to restore data)r_   r   dictr   fromisoformatr   rG   r   r   rV   r&   r%   r   r   r   r   r$   )r'   ri   r  restore_typer  r!   r+   rQ   r(   r  rp  s              r)   restore_user_datazMongoHandler.restore_user_data  s   W	K==// b#(5`aaa k400 SJk4Q4Q#(5QRRRNF000W5K5KF
 !,G 4 e e'4//D4F/191G\HZ1[1[D.'4//D4F/191G\HZ1[1[D. "&!6!A!A$!G!G!- e*a/NN"MM*cTXXgW`EaEa*c*cdddde ! F F FMM"DCFF"D"DEEEEEEEEF 555,+:U:UK
 &1%> 
o 
o	'944<9P46>6LYWcMd6e6eIl3 "&!;!;I!F!F!- o*a/NN"MM*m)--X_ajJkJk*m*mnnnn
o ! K K KMM"IQ"I"IJJJJJJJJK 4449S9SJ
 %0$< 
L 
L'8338N35=5KHUaLb5c5cH\2 "&!:!E!Eh!O!O!- L*a/NN"MM*JKKKK
L ! J J JMM"HA"H"HIIIIIIIIJ KKf}ffP\fffgggU^UUU"0 	    	K 	K 	KLL:#a&&::;;;$1IJJJJJJJJ	Ks   K# K# K# B0C8 7K# 8
D1%D,'K# ,D11K# =BG K# 
G>%G94K# 9G>>K# 
A0I; :K# ;
J4%J/*K# /J44.K# #
L&-.L!L&!L&c                    	 | j                             d|i          }|sdddS |                    dd          }ddddddddddddddddddddddddd	}|                    ||d                   }d||d
S # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)z"Get user permissions based on roler3   Fr   r/   r6   r+   Tcan_create_userscan_delete_userscan_update_user_rolescan_view_all_userscan_view_system_statscan_backup_datacan_restore_datacan_export_datacan_manage_systemcan_view_analyticscan_manage_test_casesrl   )r0   permissionsr6   z Error getting user permissions: #Failed to retrieve user permissionsNr\   )r'   r^   r+   r6   r  user_permissionsr(   s          r)   get_user_permissionsz!MongoHandler.get_user_permissions3  sM   /	X(115'2BCCD G#(5EFFF88FF++D
 )-(,-1*.-1'+(,'+)-*.-1  ).(--2*/-2',(-',).*.-1  K:  +t[5HII  /    	X 	X 	XLLDCFFDDEEE$1VWWWWWWWW	Xs#   "A: AA: :
B=.B82B=8B=c                    	 | j                             d|i          }|sdddS |                    d          dk    rdddS |rG|                     |          }|d         sdd	dS |d
                             |d          s	dd| ddS dddS # t          $ r9}t
                              dt          |                      dddcY d}~S d}~ww xY w)zEValidate if user has admin access and specific permission if requiredr3   Fr   r/   r6   rN   ra   r0   r  r  zAccess denied. z permission required.TzAccess grantedzError validating admin access: zFailed to validate accessN)r   r>   rV   r  r&   r   r$   r%   )r'   r^   required_permissionr+   r  r(   s         r)   validate_admin_accessz"MongoHandler.validate_admin_accessf  sE   	N(115'2BCCD G#(5EFFFxx7**#(5`aaa" w"77@@"9- `',9^___"=1556I5QQ w',9uK^9u9u9uvvv#0@AAA 	N 	N 	NLLC3q66CCDDD$1LMMMMMMMM	Ns4   "B B #B '$B B 
C.C	CCd   c                    	 |                      |          sdddS i }|r||d<   |r||d<   g }d|t          |          ddS # t          $ r9}t                              d	t          |                      dd
dcY d}~S d}~ww xY w)z!Get user audit trail (admin only)Fra   r/   r^   action_typeTz'Audit trail feature not yet implemented)r0   
audit_logsr   r1   z Error getting user audit trail: zFailed to retrieve audit trailN)r_   r   r&   r   r$   r%   )r'   ri   r^   r  r   r   r  r(   s           r)   get_user_audit_trailz!MongoHandler.get_user_audit_trail~  s    	S==// b#(5`aaa E +#*i  3'2m$ J  (ZD	    	S 	S 	SLLDCFFDDEEE$1QRRRRRRRR	Ss"   A %A 
B.B :B Bc                 j   	 ||||t          j                    ddd}| j        j        }|                    |          }|j        r%t                              d| d|            dddS dd	dS # t          $ r9}t          	                    d
t          |                      dddcY d}~S d}~ww xY w)z!Log admin actions for audit trailN)ri   r  	target_iddetailsr;  
ip_address
user_agentzAdmin action logged: z by TzAction logged successfullyr/   FzFailed to log actionzError logging admin action: zFailed to log admin action)r   rF   r   admin_audit_logsrG   r   r   r   r&   r$   r%   )	r'   ri   r  r  r  audit_entryaudit_collectionrQ   r(   s	            r)   log_admin_actionzMongoHandler.log_admin_action  s   	O "/*&"%_.."" K  $w7%00==F! MTKTT]TTUUU#'4PQQQ#(5KLLL 	O 	O 	OLL@A@@AAA$1MNNNNNNNN	Os$   A'A/ *A/ /
B29.B-'B2-B2c                 p   	 |                      |          sdddS i }|r||d<   t          | j                            |dddddddd                              dd                              |                    }|D ]`}d	|v rt          |d	                   |d	<   d
|v r|d
                                         |d
<   d|v r|d                                         |d<   ad|t          |          dS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)z)Get user session information (admin only)Fra   r/   r^   rb   )r3   r^   r7   rN  r  r  r9   rN  r   r3   r7   T)r0   sessionsr   zError getting user sessions: z Failed to retrieve user sessionsN)r_   rf   r   rg   r   r   r%   rh   r   r&   r   r$   )r'   ri   r^   r   r   r  sessionr(   s           r)   get_user_sessionszMongoHandler.get_user_sessions  s   "	U==// b#(5`aaa E +#*i  D9>>u!"G G   tOR((u7 7H $ T TG##%(%8%8GEN7**,3L,A,K,K,M,MGL)"g--/6/G/Q/Q/S/SGO,#CMMRRR 	U 	U 	ULLAQAABBB$1STTTTTTTT	Us#   C2 CC2 2
D5<.D0*D50D5c                    	 |                      |          sdddS i }|r||d<   |r||d<   | j                            |ddt          j                    di          }|j        dk    r3t                              d	| d
|j         d           d|j         ddS dddS # t          $ r9}t          	                    dt          |                      dddcY d}~S d}~ww xY w)z$Terminate user sessions (admin only)Fra   r/   r^   r3   rT   )r9   terminated_atr   z"User sessions terminated by admin r{   z	 sessionsTz! sessions terminated successfullyzNo sessions found to terminatez!Error terminating user sessions: zFailed to terminate sessionsN)r_   r   update_manyr   rF   rq   r   r   r&   r$   r%   )r'   ri   r^   
session_idr   rQ   r(   s          r)   terminate_user_sessionsz$MongoHandler.terminate_user_sessions  sP   	Q==// b#(5`aaa E +#*i  *)e 2>>ux?P?PQQR F
 $q((rrrRXRgrrrsss#'v7L4o4o4oppp#(5UVVV 	Q 	Q 	QLLESVVEEFFF$1OPPPPPPPP	Qs)   B  A>B  B   
C#*.CC#C#c                    	 |                      |          sdddS i }|r||d<   t          | j                            |dddddd                              dd                              |                    }|D ]j}d	|v rt          |d	                   |d	<   d
|v r|d
                                         |d
<   d|v r'|d         r|d                                         nd|d<   kd|t          |          dS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)z#Get user login history (admin only)Fra   r/   r^   rb   )r3   r-   r5   r8   r7   r8   r   r3   r7   NT)r0   login_historyr   z"Error getting user login history: z Failed to retrieve login history)r_   rf   r   rg   r   r   r%   rh   r   r&   r   r$   )r'   ri   r^   r   r   r   r+   r(   s           r)   get_user_login_historyz#MongoHandler.get_user_login_history  s    	U==// b#(5`aaa E +#*i  .33E< <   tL"%%eeEll4 4E  h hD=="%d5k"2"2DK4'')-l);)E)E)G)GD&4''KOP\K])gl);)E)E)G)G)GcgD&#ec%jjQQQ 	U 	U 	ULLFc!ffFFGGG$1STTTTTTTT	Ur~  monthc                 f   	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }nQ|d	k    r| |d
          z
  }n;|dk    r| |d          z
  }n%|dk    r| |d          z
  }n| |d          z
  }dd|ii}|r||d<   t	          | j                            d|iddddiddidddddgiddgiidig                    }	g }
|	D ]}| j                            d|d         idddd          }|rt          |d                   |d         |d          |
                    d!d"          |d#         |
                    d$d          |
                    d%d          d&z  d'}|
                    |           |
                    d( d)*           d)||                                |                                |
t          |
          d+S # t          $ r9}t                               d,t          |                      dd-dcY d.}~S d.}~ww xY w)/z)Get user performance metrics (admin only)Fra   r/   r   r
   r   rb   r.  weekweeksr  rG  yearm  r7   r   r^   $matchrH  rI  rJ  $avg$completion_time$cond$eq$status	completed)r3   r  avg_completion_timesuccess_rater3   r5   r-   r6   r5   r-   r6   r+   r  r  r  r  )r^   r5   r-   r6   r  r  r  c                     | d         S )Nr  r   xs    r)   <lambda>z;MongoHandler.get_user_performance_metrics.<locals>.<lambda>^  s    A.@,A r   Tr  reverse)r0   time_period
start_dateend_dateuser_metricsr   z(Error getting user performance metrics: z&Failed to retrieve performance metricsN)r_   r   r   rF   rf   r   r_  r   r>   r%   rV   r   r   rh   r   r&   r   r$   )r'   ri   r^   r  r   r   r=  r  r   test_case_metricsr  metricr+   user_metricr(   s                  r)   get_user_performance_metricsz)MongoHandler.get_user_performance_metrics"  s6   G	[==// b#(5`aaa 54444444!(/##Ce## 99!#4#4#44

&& 991#5#5#55

'' 99"#5#5#55

&& 99##6#6#66

 99"#5#5#55
 "FJ#78E +#*i  !%T_%>%>5!%)/,24F+G%+gK@X8Y[\^_7`-a$b	  @ & & ! ! L+ 5 5,55ufUm6LO O    
5#&ve}#5#5 $V!%g $ 8 8,23E,F/5zz:OQR/S/S(.

>1(E(E(K# #K !''444 "A"A4PPP  *(2244MMOO ,"<00    	[ 	[ 	[LLLCFFLLMMM$1YZZZZZZZZ	[s#   G- GG- -
H07.H+%H0+H0c                 2   	 |                      |          sdddS 	 | j                                         d}n)# t          $ r}dt	          |           }Y d}~nd}~ww xY wi }dD ]\}	 | j        |         }|                    i           }d|d||<   .# t          $ r"}dt	          |           d	d||<   Y d}~Ud}~ww xY wd	dl}	 |                    d
          }	|	                                }
|
                    d          }|	|
j        |j        dd}n# t          $ r ddd}Y nw xY wd}|dk    rd}|                                D ]}|d         dk    rd} n|t          j                                                    |dd||g d}|dk    r|d                             d           |                    dd	          dk    r|d                             d           |                    dd	          dk    r|d                             d           |                    dd	          dk    r|d                             d            d!|d"S # t          $ r9}t&                              d#t	          |                      dd$dcY d}~S d}~ww xY w)%r)  Fra   r/   r  zunhealthy: N)r   r   r   r   r,  r   rb   )interval/	available)cpu_percentmemory_percentdisk_percentrd   zpsutil not availablez5Install psutil package for system resource monitoring)rd   r1   r+  rd   MongoDB)rd   
connection)r8  r;  databaserA  system_resourcesrecommendationsr	  z/Check database connection and collection accessr  P   zHigh CPU usage detectedr  ry  r  Z   zLow disk space detectedT)r0   health_statusz$Error getting system health status: z'Failed to retrieve system health status)r_   r   r   r&   r%   r   r   psutilr  virtual_memory
disk_usagepercentImportErrorr?  r   rF   rh   r   rV   r   r$   )r'   ri   r@  r(   r:  rB  r   r   r  r  memorydiskr  r8  collection_statusr  s                   r)   get_system_health_statusz%MongoHandler.get_system_health_statusm  s   V	\==// b#(5`aaa3'')))%		 3 3 32#a&&22						3 "$#X  !%!9J&66r::E"+*/; ;&77 !   "8A"8"8*+; ;&777777 MMM$00!0<<..00((-- $/&,n$(L)	$ $      4V$ $    'NI%%!,%7%>%>%@%@  !$X.);;%0NE <
 #1%_..88::'"+   2$4#%
 
M ,,/0778ijjj##M155::/0778QRRR##$4a882==/0778TUUU##NA66;;/0778QRRR#mDDD 	\ 	\ 	\LLHAHHIII$1Z[[[[[[[[	\s   I 9 I 
AAI A	I )*BI 
C B;6I ;C  I AD I D+(I *D++D'I 
J.JJJc                    	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }nQ|d	k    r| |d
          z
  }n;|dk    r| |d          z
  }n%|dk    r| |d          z
  }n| |d          z
  }t	          | j                            ddd|iiidddddiddddiddididdddiddd iid!d"dd#id$id%d&diig                    }t	          | j                            ddd|iiidddddiddid'id%d&diig                    }t	          | j                            dd(d|iiidddd)diddid*id%d&diig                    }	i }
|}||k    r6|                    d          }|ddddi d+|
|<   | |d          z  }||k    6|D ]\}|d&         }||
v rN|d,         |
|         d,<   |d-         |
|         d-<   |d.         D ]#}|d/         }|d0         }||
|         d.         |<   $]|D ]}|d&         }||
v r|d1         |
|         d1<    |	D ]}|d&         }||
v r|d2         |
|         d2<    t	          |
	                                          }|
                    d3 4           d5||                                |                                |t          |          d6S # t          $ r9}t                              d7t!          |                      dd8dcY d9}~S d9}~ww xY w):z&Get user activity summary (admin only)Fra   r/   r   r
   r   rb   r.  r  r  r  rG  r  r  r  r7   r   rH  $dateToString%Y-%m-%drL  r   daterY  )r  r   rJ  	$addToSetrI  )r3   r   r   z	$_id.date$count$sizez$users$push$_id.source_typer   r   )r3   r  unique_userssource_typesrX  r3   r3   	new_usersr8   $last_loginr3   r   )r  r  r!  r$  r   r"  r  r!  r"  r   r   r$  r   c                     | d         S )Nr  r   r  s    r)   r  z8MongoHandler.get_user_activity_summary.<locals>.<lambda>6  s
    QvY r   r  T)r0   r  r  r  activity_summary
total_daysz%Error getting user activity summary: z#Failed to retrieve activity summaryN)r_   r   r   rF   rf   r   r_  r   strftimer?  r   rh   r   r&   r   r$   r%   )r'   ri   r  r   r   r=  r  r)  user_registration_summarylogin_activity_summarycombined_summarycurrent_datedate_strsummarysource_type_infor   r   activity_summary_listr(   s                      r)   get_user_activity_summaryz&MongoHandler.get_user_activity_summary  s"   z	X==// b#(5`aaa 54444444!(/##Ce## 99!#4#4#44

&& 991#5#5#55

'' 99"#5#5#55

&& 99##6#6#66

 99"#5#5#55
  $DO$=$=L6:*>?@!0ZQ^2_2_ `'5  %a[):6   &)/(:%+gx-@$A+=%-" "%	
 
 
 5!*%+? % %    2 )-T-B-L-LL6:*>?@+
M-Z-Z["(!   5!*%N . . ) )% &*$*?*I*IL6:*>?@+
M-Z-Z[%+QK   5!*%K + + & &"  " &L#%%'00<<$()$%!"$%$&. . * 		q 1 1 11 #%% , 
X 
X"5>///ELM_E`$X./ABAHAX$X.~> -4N,C X X(&6}&E 0 9RW(2>B;OO 5 S S"5>///>Ek>R$X.{; 2 Y Y"5>///AHAX$X.~> %))9)@)@)B)B$C$C!!&&+>+>&???  *(2244MMOO$9!"788    	X 	X 	XLLIQIIJJJ$1VWWWWWWWW	Xs#   K J+K 
L.L LLc                    	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }nQ|d	k    r| |d
          z
  }n;|dk    r| |d          z
  }n%|dk    r| |d          z
  }n| |d          z
  }| j                            i           }| j                            dd|ii          }| j                            dd|ii          }	t          | j                            ddd|ii                    }
|dk    r||z  dz  nd}|dk    r|
|z  dz  nd}|dk    r||	z
  |z  dz  nd}t          | j        
                    ddd|iiiddddididdddiddiddidig                    }|r|d         ndddd}t          | j        
                    ddd|iiidd ddid!id"d#d$iig                    }t          | j        
                    dd%ddid!id"d#d$iig                    }||                                |                                |||	|
t          |d&          t          |d&          t          |d&          t          |d'         d&          |d(         |d)         d||d*}d+|d,S # t          $ r9}t                              d-t!          |                      dd.dcY d}~S d}~ww xY w)/z(Get user engagement metrics (admin only)Fra   r/   r   r
   r   rb   r.  r  r  r  rG  r  r  r8   r   r7   r^   r  r  rH  rI  rJ  )r3   activity_countNr  z$activity_countrK  $min)r3   avg_activity_per_usermax_activitymin_activity)r8  r9  r:  rY  rZ  rX  r   r   z$rolerx  r8  r9  r:  )r  r  r  r   r   r$  users_with_activityengagement_rateactivity_rateretention_rateactivity_statssource_type_distributionrole_distributionT)r0   engagement_metricsz'Error getting user engagement metrics: z%Failed to retrieve engagement metrics)r_   r   r   rF   r   r   r   r   distinctrf   r_  rh   roundr&   r   r$   r%   )r'   ri   r  r   r   r=  r  r   r   r$  r;  r<  r=  r>  user_activity_frequencyr?  r@  rA  rB  r(   s                       r)   get_user_engagement_metricsz(MongoHandler.get_user_engagement_metricsE  s   k	Z==// b#(5`aaa 54444444!(/##Ce## 99!#4#4#44

&& 991#5#5#55

'' 99"#5#5#55

&& 99##6#6#66

 99"#5#5#55
 /??CCK  0@@vz2B  L
 -==vz2?  I
 #&do&>&>yvz2K ' ' # #
 EPRSOO|k9C??YZOITWX0;>DD^_MP[^_P_P_{Y6+EKKefN '+4?+D+DL6:*>?@%'-qk   .46G-H%+->$?%+->$?	  F , , ' '# <S 4Q77)* ! !Y YN (,DO,E,EL6:*>?@)$a[   7B-(G - - ( ($ !%T%:%D%D"$a[   7B-(F & & ! !  +(2244MMOO* ,&':#(!#<#<!&}a!8!8"'":":-2>BY3Z\]-^-^$2>$B$2>$B# #
 -E%6#" "(  $;MNNN 	Z 	Z 	ZLLK3q66KKLLL$1XYYYYYYYY	Zs#   J I<J 
K#.KKKc                    	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }nQ|d	k    r| |d
          z
  }n;|dk    r| |d          z
  }n%|dk    r| |d          z
  }n| |d          z
  }t	          | j                            ddd|iiiddddidddddgiddgiididddddddgid gid!ig                    }g }|D ]}	d}
|	d"         dk    r>|	d#         d$k    rd%}
n/|	d#         d&k    rd'}
n |	d#         d(k    rd)}
n|	d#         d*k    rd+}
nd}
|                    |	d,         |
t          |	d#         d+          |	d"         d-           |r`t          d. |D                       t          |          z  }i }t          dd/          D ]#t          fd0|D                       |d1 <   $nd}d2 t          dd/          D             }g }|D ]}| j                            d3|d,         iddddd4          }|r|                    |d,         |d5         |d6         |                    d7d8          |d9         |d#         |d"         |                    d          r|d                                         nd:d;           |                    d< d=>           ||                                |                                t          |d+          |t          |          |t          d? |D                       t          d@ |D                       t          dA |D                       t          dB |D                       t          dC |D                       dDdE}d=|dFS # t"          $ r9}t$                              dGt)          |                      ddHdcY d:}~S d:}~ww xY w)Iz2Get user feedback and ratings metrics (admin only)Fra   r/   r   r
   r   rb   r.  r  r  r  rG  r  r  r  r7   r   rH  rI  rJ  r  r  r  r  )r3   r  successful_test_casesrT  rU  z	$multiply$dividez$successful_test_casesz$total_test_casesr  )r^   r  r  r  r  r     r
     F   rz  <   rx  r^   )r^   satisfaction_scorer  r  c              3   &   K   | ]}|d          V  dS rN  Nr   r   us     r)   r6  z9MongoHandler.get_user_feedback_metrics.<locals>.<genexpr>  s(      &Z&Z1q)='>&Z&Z&Z&Z&Z&Zr      c                 ,    g | ]}|d          k    |S rN  r   )r   rR  r   s     r)   
<listcomp>z:MongoHandler.get_user_feedback_metrics.<locals>.<listcomp>  s7      CA  CA  CAcdeycz~cc1cccr   score_c                     i | ]}d | d	S )rW  r   r   )r   r   s     r)   r   z:MongoHandler.get_user_feedback_metrics.<locals>.<dictcomp> 	  s     ,R,R,R\a\\1,R,R,Rr   r3   r5   r-   r6   r7   r5   r-   r6   r+   rN  N)r^   r5   r-   r6   rN  r  r  
user_sincec                     | d         S NrN  r   r  s    r)   r  z8MongoHandler.get_user_feedback_metrics.<locals>.<lambda>	  s    CWAX r   Tr  c                 *    g | ]}|d          dk    |S r  r  r   rQ  s     r)   rV  z:MongoHandler.get_user_feedback_metrics.<locals>.<listcomp>%	  s(    %^%^%^AaFW[]F]F]aF]F]F]r   c                 >    g | ]}d |d         cxk    rdk     n n|S r
  r  r  r   rQ  s     r)   rV  z:MongoHandler.get_user_feedback_metrics.<locals>.<listcomp>&	  s?     ^ ^ ^qqGXA]A]A]A][]A]A]A]A]A]A]A]A]r   c                 >    g | ]}d |d         cxk    rdk     n n|S rL  r  r
  r   rQ  s     r)   rV  z:MongoHandler.get_user_feedback_metrics.<locals>.<listcomp>'	  s?    #a#a#a!B!NJ[D`D`D`D`^`D`D`D`D`D`AD`D`D`r   c                 >    g | ]}d |d         cxk    rdk     n n|S rM  r  rL  r   rQ  s     r)   rV  z:MongoHandler.get_user_feedback_metrics.<locals>.<listcomp>(	  A    )g)g)g"PQR`PaJfJfJfJfdfJfJfJfJfJf!JfJfJfr   c                 *    g | ]}|d          dk     |S r  rM  r   rQ  s     r)   rV  z:MongoHandler.get_user_feedback_metrics.<locals>.<listcomp>)	  s(     X X Xq>ARUWAWAWAWAWAWr   )	excellentgoodaveragebelow_averagepoor)r  r  r  overall_satisfactionsatisfaction_distributiontotal_users_analyzeduser_satisfaction_detailssuccess_rate_summary)r0   feedback_metricsz%Error getting user feedback metrics: z#Failed to retrieve feedback metrics)r_   r   r   rF   rf   r   r_  r   rD  sumr   ranger   r>   rV   rh   r   r&   r   r$   r%   )r'   ri   r  r   r   r=  r  test_case_success_ratesuser_satisfactionr  rN  avg_satisfactionrn  !activity_satisfaction_correlationr+   user_detailsrr  r(   r   s                     @r)   get_user_feedback_metricsz&MongoHandler.get_user_feedback_metrics  s   {	X==// b#(5`aaa 54444444!(/##Ce## 99!#4#4#44

&& 991#5#5#55

'' 99"#5#5#55

&& 99##6#6#66

 99"#5#5#55
 '+4?+D+DL6:*>?@%)/EI{3K+LaQR*S T.   %()#&)ACV(WX&%	 	 	F , , ' '#. !#6  %&"12Q66">2b88-.**$^4::-.**$^4::-.**$^4::-.**-.*!((*95*<$)+n*Eq$I$I(34F(G	* *     ! S#&&Z&ZHY&Z&Z&Z#Z#Z]`ar]s]s#s ,.)q! B BA>A  CA  CA  CA  CAN_  CA  CA  CA  ?B  ?B-lqll;;B $% ,R,ReAqkk,R,R,R) 13-)  #4==ud9o>V"#	Y Y       
5<<#'	? ,V 4!-g!6 , 0 0 @ @.23G.H(,^(<,01C,DP\P`P`amPnPn&xl<&@&J&J&L&L&Ltx	> 	> 	 	 	 .227X7Xbf2ggg  +(2244MMOO(-.>(B(B-F(+,=(>(>-N!$%^%^1B%^%^%^!_!_ ^ ^,= ^ ^ ^__"#a#a/@#a#a#abb%()g)g5F)g)g)g%h%h X X,= X X XYY) )   "  $9IJJJ 	X 	X 	XLLIQIIJJJ$1VWWWWWWWW	Xs#   N M/N 
O.OOOr  c                 	   	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }d	}nA|d
k    r| |d          z
  }d}n)|dk    r| |d          z
  }d	}n| |d          z
  }d	}t	          | j                            ddd|iiidd|ddiddididddiig                    }t	          | j                            ddd|iiidd|ddiddidddiididddiig                    }	t	          | j                            ddd|iiidd|d diddid!idddiig                    }
i |}||k    r|dk    r|                    d	          }n8|d
k    r|j	        dz
  d"z  dz   }|j
         d#| }n|                    d	          }|ddddddd$|<   |dk    r| |d          z  }n%|d
k    r| |d          z  }n| |d          z  }||k    |D ]}|d         }|v r|d%         |         d%<    |	D ]0}|d         }|v r"|d&         |         d&<   |d'         |         d'<   1|
D ]}|d         }|v r|d(         |         d(<    t                                                    }t          |          D ]\  }}|dk    r\||dz
           }|         d%         }|         d%         }|dk    r||z
  |z  d)z  }n
|dk    rd)nd}t          |d*          |         d+<   t          fd,|d-|dz            D                       }|dk    r|         d(         |z  d)z  }nd}t          |d*          |         d.<   t	                                                    }t          d/ |D                       }t#          d0 |D                       r3t          d1 |D                       t%          d2 |D                       z  nd}|r)t          d3 |D                       t%          |          z  nd}||                                |                                |t          |d*          t          |d*          ||rt)          |d4 5          nd-|rt)          |d6 5          nd-t%          |          d7d8}d9|d:S # t*          $ r9}t,                              d;t1          |                      dd<dcY d-}~S d-}~ww xY w)=z#Get user growth trends (admin only)Fra   r/   r   r
   r  rG  r.  %Y-%mquarterr  z%Y-Q%qr  r  r  r7   r   rH  r  rL  r  rJ  rb   r#  rX  r3   r  r  rI  )r3   total_activitiesr!  r8   r%  r&  rz  z-Q)periodr$  r~  r!  r   growth_rater=  r$  r~  r!  r   r  rx  r  c              3   4   K   | ]}|         d          V  dS r$  Nr   )r   pcombined_trendss     r)   r6  z6MongoHandler.get_user_growth_trends.<locals>.<genexpr>	  s.      +c+cPQOA,>{,K+c+c+c+c+c+cr   Nr=  c              3   &   K   | ]}|d          V  dS r  r   r   trends     r)   r6  z6MongoHandler.get_user_growth_trends.<locals>.<genexpr>	  s'      !U!U%"4!U!U!U!U!U!Ur   c              3   .   K   | ]}|d          dk    V  dS r  r   Nr   r   ts     r)   r6  z6MongoHandler.get_user_growth_trends.<locals>.<genexpr>	  sh        |o  |o  WX  }~  L  }M  QR  }R  |o  |o  |o  |o  |o  |or   c              3   >   K   | ]}|d          dk    |d          V  dS r  r   r  s     r)   r6  z6MongoHandler.get_user_growth_trends.<locals>.<genexpr>	  s9      !t!t5Z_`mZnrsZsZs%"6ZsZsZsZs!t!tr   c                 *    g | ]}|d          dk    |S )r  r   r   r  s     r)   rV  z7MongoHandler.get_user_growth_trends.<locals>.<listcomp>	  s`      |t  |t  |t  CD  ^_  `m  ^n  rs  ^s  ^s|}  ^s  ^s  ^sr   c              3   &   K   | ]}|d          V  dS )r=  Nr   r  s     r)   r6  z6MongoHandler.get_user_growth_trends.<locals>.<genexpr>	  s'      #[#[uE/$:#[#[#[#[#[#[r   c                     | d         S )Nr  r   r  s    r)   r  z5MongoHandler.get_user_growth_trends.<locals>.<lambda>	  s    PQR_P` r   r(  c                     | d         S )Nr=  r   r  s    r)   r  z5MongoHandler.get_user_growth_trends.<locals>.<lambda>	  s    RSTcRd r   )best_growth_periodbest_activity_periodtotal_periods)r  r  r  total_new_usersaverage_growth_rateaverage_activity_ratetrendsr1  T)r0   growth_trendsz"Error getting user growth trends: z Failed to retrieve growth trends)r_   r   r   rF   rf   r   r_  r   r+  r  r  sortedr   	enumeraterD  rs  r?  r>  r   rh   maxr&   r   r$   r%   )r'   ri   r  r   r   r=  r  date_formatuser_registration_trendsuser_activity_trendsuser_login_trendsr/  
period_keyr}  r  periodsr   r  prev_period
prev_userscurrent_usersr  total_users_in_periodr=  growth_trends_listr  avg_growth_rateavg_activity_rater  r(   r  s                                 @r)   get_user_growth_trendsz#MongoHandler.get_user_growth_trends3	  s   Z	U==// b#(5`aaa 54444444!(/##Cg%% 99"#5#5#55
%	)) 99"#5#5#55
&&& 99##6#6#66
% 99##6#6#66
% (,D,A,K,KL6:*>?@+]-[-[\"(!   5!*%M - - ( ($ $((A(AL6:*>?@+]-[-[\)/%,{J.G$H  
 5!*%C ) ) $ $  !%T%:%D%DL6:*>?@+]-[-[\%+QK   5!*%F & & ! ! !O &L#%%'))!-!6!6w!?!?JJ I--+1A5!;a?G$0$5!B!B!B!BJJ!-!6!6w!?!?J )!"()$%$%#$%&/ /
+ ')) II2$6$6$66LL I-- II2$6$6$66LL II2$6$6$66L1 #%%6 2 R R"5\
00?D[?QOJ/< . X X"5\
00FKL^F_OJ/0BCBGBWOJ/? + X X"5\
00BGBWOJ/? _113344G&w// S S	6q55")!A#,K!0!=k!JJ$3F$;K$HM!A~~(5
(Bj'PTW&W-:Q->->ccA=B;PQ=R=ROF+M: ),+c+c+c+cU\]a^_`a^a]aUb+c+c+c(c(c%(1,,%4V%<^%LOd%dhk$kMM$%M;@PQ;R;R'88 "&o&<&<&>&>!?!? "!U!UBT!U!U!UUUO y|  |o  |o  \n  |o  |o  |o  yo  yo  vc!t!tDV!t!t!tttwz  |t  |t  HZ  |t  |t  |t  xu  xu  u  u  uvO zL  !S#[#[HZ#[#[#[ [ [^abt^u^u u u  RS  +(2244MMOO#2',_a'@'@)./@!)D)D,ew  +B#.@F`F`*a*a*a*a  ~Bi{  -FC0BHdHd,e,e,e,e  BF%();%<%<  M  $mDDD 	U 	U 	ULLFc!ffFFGGG$1STTTTTTTT	Us#   R' R	R' '
S*1.S%S*%S*c                 	   	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }n;|d	k    r| |d
          z
  }n%|dk    r| |d          z
  }n| |d
          z
  }g }|}||k    r| |d          z   }	t	          | j                            d||	diddd                    }
|
rt          |
          }d |
D             }g d}i }|D ]n}|	 ||dz
            z   }| |d          z   }| j        	                    d|i||dd          }|dk    r||z  dz  nd}|t          |d          d|d| <   o|                    |                                |	                                ||d           |	}||k    t          |          }|dk    rqt          d |D                       |z  }t          d |D                       |z  }t          d |D                       |z  }t          d |D                       |z  }ndx}x}x}}g }|D ]} |j        |d                   } |j        |d                    }	d|d!         d"         d#         z
  }|                    |                    d$           d%|	                    d$           |d&         |d!         d'         d#         |d!         d"         d#         t          |d          d(           t	          | j                            d)dd*|iiid+d,d-did.d/id0d/id1id2d3dd4d5d6d7gid8gid9ig                    }|rSt          d: |D                       t          |          z  }t          d; |D                       t          |          z  }ndx}}||                                |                                ||t          |d          t          |d          t          |d          t          |d          d<|t          |          t          |d          t          |d          d=d>} d?| d@S # t"          $ r9}!t$                              dAt)          |!                      ddBdcY dC}!~!S dC}!~!ww xY w)Dz(Get user retention analysis (admin only)Fra   r/   r   r
   r  rK  r  r  r  r.  r}     rb   r7   r   z$lt)r3   r7   c                     g | ]
}|d          S )r3   r   r   r+   s     r)   rV  z<MongoHandler.get_user_retention_analysis.<locals>.<listcomp>	  s    &L&L&LttE{&L&L&Lr   )rb   rx  rz  rK  z$inr   r  rx  )r   r>  week_)cohort_start
cohort_endcohort_sizeretention_datac              3   >   K   | ]}|d          d         d         V  dS )r  week_1r>  Nr   r   cohorts     r)   r6  z;MongoHandler.get_user_retention_analysis.<locals>.<genexpr>
  4      *~*~dj62B+CH+MN^+_*~*~*~*~*~*~r   c              3   >   K   | ]}|d          d         d         V  dS )r  week_2r>  Nr   r  s     r)   r6  z;MongoHandler.get_user_retention_analysis.<locals>.<genexpr>
  r  r   c              3   >   K   | ]}|d          d         d         V  dS )r  week_3r>  Nr   r  s     r)   r6  z;MongoHandler.get_user_retention_analysis.<locals>.<genexpr>
  r  r   c              3   >   K   | ]}|d          d         d         V  dS )r  week_4r>  Nr   r  s     r)   r6  z;MongoHandler.get_user_retention_analysis.<locals>.<genexpr>
  r  r   r  r  r  r  r>  r  z to r  r  )cohort_periodr  week_1_retentionweek_4_retention
churn_rater  r   rH  rI  rJ  r7  rL  rK  )r3   r  first_activityrN  rT  rU  rI  	$subtract$last_activity$first_activity \&)r^   r  lifetime_daysc              3   &   K   | ]}|d          V  dS )r  Nr   r  s     r)   r6  z;MongoHandler.get_user_retention_analysis.<locals>.<genexpr>K
  s'      'a'a$_(='a'a'a'a'a'ar   c              3   &   K   | ]}|d          V  dS r  Nr   r  s     r)   r6  z;MongoHandler.get_user_retention_analysis.<locals>.<genexpr>L
  s(      -j-j4d3E.F-j-j-j-j-j-jr   )r  week_2_retentionweek_3_retentionr  )ro  average_lifetime_daysaverage_test_cases_per_user)r  r  r  total_cohortscohort_analysisoverall_retention_metricschurn_analysisuser_lifetime_analysisT)r0   retention_analysisz'Error getting user retention analysis: z%Failed to retrieve retention analysisN)r_   r   r   rF   rf   r   rg   r   r   r   rD  r   rh   rs  r  r+  r_  r&   r   r$   r%   )"r'   ri   r  r   r   r=  r  r  current_cohort_startr  cohort_usersr  cohort_user_idsretention_periodsr  r  period_start
period_endr   r>  r  avg_week_1_retentionavg_week_2_retentionavg_week_3_retentionavg_week_4_retentionr  r  r  r  r  avg_lifetime_daysavg_test_cases_per_userr  r(   s"                                     r)   get_user_retention_analysisz(MongoHandler.get_user_retention_analysis	  s   U	Z==// b#(5`aaa 54444444!(/##Cf$$ 991#5#5#55

'' 99"#5#5#55

	)) 99##6#6#66

 99"#5#5#55
 !O $. &#--1IIA4F4F4FF
  $D$9$>$>  4)# #@
 A..%0 %0  1  1    "%l"3"3K&L&L|&L&L&LO )5%%'N"3  '1IIF1H4M4M4M'M%1IIA4F4F4F%F
 (,'F'F(-'?(4'1+ +H H ( ( P[]^,*Ds*J*Jde,8.3NA.F.F< <'7v'7'788
 $**(<(F(F(H(H&0&:&:&<&<'2*8	, ,    (2$[ '#--`  00Mq  '**~*~n}*~*~*~'~'~  BO  (O$'**~*~n}*~*~*~'~'~  BO  (O$'**~*~n}*~*~*~'~'~  BO  (O$'**~*~n}*~*~*~'~'~  BO  (O$$lmm$m';m>RUi  N)  5x5f^6LMM3X3F<4HII
 !6*:#;H#EFV#WW
%%(4(=(=j(I(I%p%pzObObcmOnOn%p%p#)-#8(./?(@(JK[(\(./?(@(JK[(\"'
A"6"6' '     &*$/*C*CL6:*>?@%)/'-}&=&,m%<	   %()!(+;=N*OP/$&	 	 	E + + & &"* & @$''a'aJ`'a'a'a$a$adgh~dd$!*--j-jSi-j-j-j*j*jmp  rH  nI  nI  +I''>??!$;  +(2244MMOO!.#2(-.BA(F(F(-.BA(F(F(-.BA(F(F(-.BA(F(F	. . #1,/0F,G,G-23Da-H-H389PRS3T3T+ +" "(  $;MNNN 	Z 	Z 	ZLLK3q66KKLLL$1XYYYYYYYY	Zs#   Q P$Q 
R.Q?9R?Rc                 &   	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }nQ|d	k    r| |d
          z
  }n;|dk    r| |d          z
  }n%|dk    r| |d          z
  }n| |d          z
  }t	          | j                            ddd|iiidddiddididddiig                    }t	          | j                            ddd|iiidddiddididddiig                    }t	          | j                            ddd|iiiddddddididdddd d!idd id"idd#d$iig                    }	t	          | j                            ddd|iiidddd%d&dd'iddid(iddid)id*d+dd,d-d.iid/d0d,d-d.iigid1d2ig                    }
g }|
D ]}| j                            d|d3         idddd4          }|r|d5         }d}|d6k    rd7}n|d8k    rd9}n|dk    rd:}nd;}|	                    t          |d3                   |d<         |d=         |                    d>d?          |d#         |d@         t          |d5         dA          |dB           |                    dC dDE           g }|D ]m}|d         }|dF         }dG}dH|cxk    rdIk     rn ndJ}n(dI|cxk    rdKk     rn ndL}ndK|cxk    rdMk     rn ndN}ndO}|	                    ||||dPdQdR           ng }g dS}|D ]4}|d         }|dF         }|	                    |||dz
           |dT           5||                                |                                |||	|
||rt          |dU V          ndW|rt          |dX V          ndWt!          |          t!          dY |D                       dZd[	}dD|d\S # t"          $ r9}t$                              d]t          |                      dd^dcY dW}~S dW}~ww xY w)_z'Get user behavior patterns (admin only)Fra   r/   r   r
   r   rb   r.  r  r  r  rG  r  r  r  r7   r   rH  z$hourrL  rJ  rZ  rX  r3   z
$dayOfWeekrI  rY  )r^   r   z$_id.user_idr  r  r  r   )r3   r"  r~  r~  r   r  r  r  )r  time)r3   r  r~  rT  rU  r  z	$setUnionz$sessions.daterI  z$total_activitiesz	$sessions)r^   r~  unique_daysavg_activities_per_daysession_patternsr^   r  r  rJ  	Very Highrz  HighMediumLowr5   r-   r6   r+   r  rx  )r^   r5   r-   r6   r~  r  r  engagement_scorec                 (    ddddd| d                  S )NrK  rz  rx  rb   )r  r  r  r  r  r   r  s    r)   r  z9MongoHandler.get_user_behavior_patterns.<locals>.<lambda>
  s*    	4 4
 "#4% r   Tr  r    rS     Morning   	Afternoon   EveningNight02dz:00)r   r  r6  formatted_time)SundayMondayTuesday	WednesdayThursdayFridaySaturday)
day_numberday_namer6  c                     | d         S Nr6  r   r  s    r)   r  z9MongoHandler.get_user_behavior_patterns.<locals>.<lambda>  s    QGWEX r   r(  Nc                     | d         S r  r   r  s    r)   r  z9MongoHandler.get_user_behavior_patterns.<locals>.<lambda>  s    1EUCV r   c                 &    g | ]}|d          dv |S )r  )r  r  r   rQ  s     r)   rV  z;MongoHandler.get_user_behavior_patterns.<locals>.<listcomp>  sK      2D  2D  2DTUVhTi  nC  UC  UC!  UC  UC  UCr   )	peak_hourpeak_dayro  high_engagement_users)	r  r  r  hourly_activityweekly_patternssource_type_preferencesuser_session_patternsengagement_patternsr1  )r0   behavior_patternsz&Error getting user behavior patterns: z$Failed to retrieve behavior patterns)r_   r   r   rF   rf   r   r_  r   r>   r   r%   rV   rD  r   rh   r  r   r&   r   r$   )r'   ri   r  r   r   r=  r  r  daily_activityr
  r  r  user_patternry  activity_frequencyr  peak_usage_times	hour_datar   r   r	  	day_namesday_datar  r  r(   s                             r)   get_user_behavior_patternsz'MongoHandler.get_user_behavior_patternsj
  s!   x	Y==// b#(5`aaa 54444444!(/##Ce## 99!#4#4#44

&& 991#5#5#55

'' 99"#5#5#55

&& 99##6#6#66

 99"#5#5#55
 #4?#<#<L6:*>?@#]3$a[   5!*%> $ $  O "$/";";L6:*>?@(-8$a[   5!*%= # #  N '+4?+D+DL6:*>?@#-'5  %a[   )+=%-" "% *0(:	 	 	 -r23'F , , ' '#. %))B)BL6:*>?@%%4Ub6c6c$d%,m$<" "! *0	 	 	 %()$+k;K-L#M/8;NQX[fhxZyPz:{.|(3  D * * % %!, #% 5  #4==ulS\F]>^a a       )56N)O&'($)Q..+6((+q00+1((+q00+3((+0('..#&|I'>#?#? ,V 4!-g!6 , 0 0 @ @,89K,L'3M'B27E]8^`a2b2b,<	0 	0 	 	 	  $$ *% *%
 /3 % 4 4 4  ",  	 '!'* >>>>r>>>>>"+KK4____"_____"-KK4____"_____"+KK")K '' #.&+)-&6&6&6&6	) )     !OfffI*  %e_
 )&&", )*q. 9&+( (      +(2244MMOO#3#2+B)>':]m!w%5;X;X!Y!Y!Y!Ysw[j tO9V9V W W W Wpt,/0C,D,D-0  2D  2D=P  2D  2D  2D  .E  .E	 ! !"  $:KLLL 	Y 	Y 	YLLJ#a&&JJKKK$1WXXXXXXXX	Ys#   O N0O 
P.PPPc                 &   	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }nQ|d	k    r| |d
          z
  }n;|dk    r| |d          z
  }n%|dk    r| |d          z
  }n| |d          z
  }t	          | j                            ddd|iiiddddiddiddiddidddddgidgiid ig                    }g }|D ]}	| j                            d!|	d!         iddddd"          }
|
rd}|
	                    d          r||
d         z
  j
        }|                     |	d#         |	d$         |t          |	d%                             }|                    t          |	d!                   |
d&         |
d'         |
	                    d(d)          ||	d#         t          |	d%                   |	d%         ||	d$         rt          |	d$         d*          ndd+
           i }|D ].}|d,         }||vrg ||<   ||                             |           /i }|                                D ]\  }}t          |          }|dk    rt#          d- |D                       |z  nd}|dk    rt#          d. |D                       |z  nd}|dk    rt#          d/ |D                       |z  nd}||r#t          |t          |          z  d0z  d*          ndt          |d*          t          |d*          t          |d*          |d1||<   i }|                                D ]\  }}|d2         ri }|d2         D ])}|d%         D ]}|	                    |d          dz   ||<   *t%          |                                d3 d45          }|d6d7         |                     |d8                   |                     |d9                   d:||<   i }|                                D ]\  }}g }|d;k    r|                    g d<           nw|d=k    r|                    g d>           nY|d?k    r|                    g d@           n;|dAk    r|                    g dB           n|dCk    r|                    g dD           |||<   ||                                |                                t          |          |||||r*t/          |                                dE F          d         nd6|r*t/          |                                dG F          d         nd6t          |          dHdI	}d4|dJS # t0          $ r9}t2                              dKt          |                      ddLdcY d6}~S d6}~ww xY w)Mz+Get user segmentation analysis (admin only)Fra   r/   r   r
   r   rb   r.  r  r  r  rG  r  r  r  r7   r   rH  rI  rJ  r  rY  r7  rL  rK  r  rI  r  r  r  r  )r3   r  r"  r  rN  avg_daily_activityr3   rY  r  r  r"  r5   r-   r6   r+   rx  )
r^   r5   r-   r6   segmentr  source_types_usedr"  user_age_daysr  r  c              3   &   K   | ]}|d          V  dS r  r   rQ  s     r)   r6  z>MongoHandler.get_user_segmentation_analysis.<locals>.<genexpr>  s(      $J$JqQ'9%:$J$J$J$J$J$Jr   c              3   &   K   | ]}|d          V  dS )r  Nr   rQ  s     r)   r6  z>MongoHandler.get_user_segmentation_analysis.<locals>.<genexpr>  s'      "E"E!1_#5"E"E"E"E"E"Er   c              3   &   K   | ]}|d          V  dS )r  Nr   rQ  s     r)   r6  z>MongoHandler.get_user_segmentation_analysis.<locals>.<genexpr>  s(      &M&M!q)<'=&M&M&M&M&M&Mr   r  )r   
percentageavg_test_casesavg_age_daysavg_source_typesr   r   c                     | d         S Nrb   r   r  s    r)   r  z=MongoHandler.get_user_segmentation_analysis.<locals>.<lambda>  s    [\]^[_ r   Tr  Nrz  r  r!  )preferred_source_typesactivity_levelengagement_levelPower Users)z3Provide advanced features and customization optionsz7Offer priority support and early access to new featuresz#Consider beta testing opportunitiesActive Users)z0Encourage exploration of additional source typesz0Provide tips for optimizing test case generationz+Offer training materials and best practicesRegular Users)z7Increase engagement through notifications and remindersz'Provide onboarding and tutorial contentz%Offer incentives for consistent usageOccasional Users)zImprove onboarding experiencezProvide quick-start templateszSend re-engagement campaigns	New Users)z Provide comprehensive onboardingz Offer guided tours and tutorialszSet up welcome series emailsc                     | d         d         S )Nrb   r   r   r  s    r)   r  z=MongoHandler.get_user_segmentation_analysis.<locals>.<lambda>  s    UVWXUYZgUh r   r(  c                     | d         d         S )Nrb   r  r   r  s    r)   r  z=MongoHandler.get_user_segmentation_analysis.<locals>.<lambda>  s    YZ[\Y]^nYo r   )largest_segmentmost_active_segmenttotal_segments)	r  r  r  ro  segment_groupssegment_statisticssegment_behaviorsegment_recommendationsr1  )r0   segmentation_analysisz*Error getting user segmentation analysis: z(Failed to retrieve segmentation analysis)r_   r   r   rF   rf   r   r_  r   r>   rV   r/  _determine_user_segmentr   r   r%   rD  r   rs  r  _get_activity_level_description!_get_engagement_level_descriptionr   rh   r  r&   r   r$   )r'   ri   r  r   r   r=  r  user_activity_datauser_segmentsr\  ry  r  r  r1  r+   r2  r   r   r  r   r!  r3  r   source_type_countsr   sorted_source_typesr4  r	  r5  r(   s                                 r)   get_user_segmentation_analysisz+MongoHandler.get_user_segmentation_analysis&  s@   s	]==// b#(5`aaa 54444444!(/##Ce## 99!#4#4#44

&& 991#5#5#55

'' 99"#5#5#55

&& 99##6#6#66

 99"#5#5#55
 "&do&?&?L6:*>?@%)/%0.$A'-}&=&,m%<%!,/?AR.S T 3(!+  A ' ' " "( M!3 ! !#4==umTYFZ>["#	^ ^       $%M#''55 P),|L/I)I(O #::%&89%&:;%M.9::	 G "((#&}U';#<#< ,V 4!-g!6 , 0 0 @ @#*,9:L,M-0~1N-O-O(5n(E)6_l  nB  `C  /JeMBV4WYZ.[.[.[  IJ* *     N% 5 5y/.00.0N7+w'..t4444 "$"0"6"6"8"8  !%jj\gjk\k\k$J$JE$J$J$J!J!J[!X!XqrWbefWfWfs"E"Eu"E"E"EEESSlm_jmn_n_n3&M&Mu&M&M&M#M#MP[#[#[tu  $/Xe"l%s=7I7I)IC)ORS"T"T"Tkl&+NA&>&>$),$:$:(-.>(B(B"/ /"7++  ""4":":"<"<  > )+& %g i i+/+? i iK>P>T>TU`bc>d>dgh>h.{;;i +11C1I1I1K1KQ_Q_im*n*n*n' 3Fbqb2I*.*N*NuUeOf*g*g,0,R,RSXYkSl,m,m1 1$W- ')#"4":":"<"< "C "C"$m++#** , , ,    
 ..#** , , ,    
 //#** , , ,    
  222#** , , ,    
 ++#** , , ,    4C'00  +(2244MMOO(+M(:(:"0&8$4+B qC  (Ms+=+C+C+E+EKhKh'i'i'ijk'l'l  IM xJ  ,T3/A/G/G/I/IOoOo+p+p+pqr+s+s  PT&)*<&=&= % %!   $>STTT 	] 	] 	]LLNc!ffNNOOO$1[\\\\\\\\	]s#   U T0U 
V.VVVc                 ^    |dk    rdS |dk    r|dk    rdS |dk    r|dk    rdS |d	k    rd
S dS )z'Helper method to determine user segment   r+  r   rz  r'  r   rb   r(  rJ  r)  r*  r   )r'   r  r  r  source_types_counts        r)   r6  z$MongoHandler._determine_user_segment  s^    A;##(:a(?(? =##(:a(?(?!>"""?%%r   c                 6    |dk    rdS |dk    rdS |dk    rdS dS )z/Helper method to get activity level descriptionrJ  r  rz  r  rb   r  r  r   )r'   r  s     r)   r7  z,MongoHandler._get_activity_level_description  s7    Q;q  6q  85r   c                 6    |dk    rdS |dk    rdS |dk    rdS dS )z1Helper method to get engagement level descriptionrz  r  rx  r  rb   r  r  r   )r'   r!  s     r)   r8  z.MongoHandler._get_engagement_level_description  s7    q  ;""6""85r   c                    	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }nQ|d	k    r| |d
          z
  }n;|dk    r| |d          z
  }n%|dk    r| |d          z
  }n| |d          z
  }g d}i }| j                            dd|ii          }	|	ddd|d<   | j                            d|idddd          }
|
|	dk    rt          |
|	z  dz  d          nd|	dk    rt          |	|
z
  |	z  dz  d          ndd|d<   t          | j        	                    ddd|ii                    }||	dk    rt          ||	z  dz  d          nd|
dk    rt          |
|z
  |
z  dz  d          ndd|d<   t          | j        
                    ddd|iiiddd did!idd"ddiiig                    }||	dk    rt          ||	z  dz  d          nd|dk    rt          ||z
  |z  dz  d          ndd|d#<   t          | j        
                    ddd|iiiddd$d%id&idd'dd(d)idgiiig                    }||	dk    rt          ||	z  dz  d          nd|dk    rt          ||z
  |z  dz  d          ndd|d*<   t          | j        
                    ddd|iiiddd did!idd"dd+iiig                    }||	dk    rt          ||	z  dz  d          nd|dk    rt          ||z
  |z  dz  d          ndd|d,<   t          | j        
                    ddd|iiiddd did!idd"dd-iiig                    }||	dk    rt          ||	z  dz  d          nd|dk    rt          ||z
  |z  dz  d          ndd|d.<   |	dk    rt          ||	z  dz  d          nd}t          d/ |                                D                       t          |          z  }g }t          |                                d0 d1          dd2         }|D ]Y\  }}|d3         dk    rH|                    d4|                    d5d6                                           d7|d3          d8           Zt          |                                d9 d1          dd2         }|D ]Y\  }}|d:         dk    rH|                    d;|                    d5d6                                           d<|d:          d=           Zt%          | j        
                    ddd|iiiddd>d%d?d@id didAidBdCdDiidEdFig                    }g }|D ]f}t          |dG         dH I          }dJ |D             }|                    t'          |dK                   ||dC         t          |          dL           g||                                |                                |||	|t          |d          |dM||g dNdO	}d|dPS # t*          $ r9}t,                              dQt'          |                      ddRdcY d}~S d}~ww xY w)Sz0Get user conversion funnel analysis (admin only)Fra   r/   r   r
   r   rb   r.  r  r  r  rG  r  r  )
registeredfirst_loginfirst_test_casemultiple_test_casesmultiple_source_typesregular_user
power_userr7   r   r  )r   r  dropoffrD  TN$exists$ner7   r8   rx  rE  r^   rF  r  rH  rI  rJ  )r3   rM  rM  rG  r  rY  )r3   r"  z$exprr  z$source_typesrH  rJ  rI  r   rJ  c              3   &   K   | ]}|d          V  dS )r  Nr   )r   stages     r)   r6  z:MongoHandler.get_user_conversion_funnel.<locals>.<genexpr>  s'      &]&]uu\':&]&]&]&]&]&]r   c                     | d         d         S )Nrb   rK  r   r  s    r)   r  z9MongoHandler.get_user_conversion_funnel.<locals>.<lambda>  s    1i r   r  rz  rK  zBiggest dropoff at _ z stage: %c                     | d         d         S )Nrb   r  r   r  s    r)   r  z9MongoHandler.get_user_conversion_funnel.<locals>.<lambda>  s    AaDDV r   r  zBest performing stage: z with z% conversionr  rL  )r   r;  )r3   journeyr~  rX  r~  r   z$limitr   rW  c                     | d         S Nr;  r   r  s    r)   r  z9MongoHandler.get_user_conversion_funnel.<locals>.<lambda>  s
    !K. r   r(  c                     g | ]
}|d          S )r   r   )r   steps     r)   rV  z;MongoHandler.get_user_conversion_funnel.<locals>.<listcomp>  s    OOO] 3OOOr   r3   )r^   journey_pathr~  journey_length)total_registeredoverall_conversion_rateaverage_stage_conversionfinal_stage_users)z9Focus on reducing dropoff at identified bottleneck stagesz/Implement onboarding improvements for new usersz=Create engagement campaigns for users at risk of dropping offz8Provide incentives for progression through funnel stagesz?Analyze successful user journeys for optimization opportunities)	r  r  r  funnel_stagesfunnel_dataoverall_metricsfunnel_insightsuser_journeysr	  )r0   conversion_funnelz&Error getting user conversion funnel: z$Failed to retrieve conversion funnel)r_   r   r   rF   r   r   rD  r   r   rC  r_  rs  r?  r  r   r   r   r   rf   r%   rh   r&   r   r$   )r'   ri   r  r   r   r=  r  rb  rc  r^  first_login_usersusers_with_test_casesusers_with_multiple_test_casesusers_with_multiple_sourcesr   power_usersr_  avg_stage_conversionre  biggest_dropoffsrQ  r   best_stagesuser_journey_datarf  rW  sorted_journeyr\  rg  r(   s                                 r)   get_user_conversion_funnelz'MongoHandler.get_user_conversion_funnel   s~
   L	Y==// b#(5`aaa 54444444!(/##Ce## 99!#4#4#44

&& 991#5#5#55

'' 99"#5#5#55

&& 99##6#6#66

 99"#5#5#55
  M K  $4DDvz2F     *!) )K% !% 5 E E%z2*.t<<G G ! !
 +XhklXlXle%69I%IC%ORSTTTrsjz}~j~j~5#36G#GK["[^a"adefff  EF* *K& %((@(@vz2M ) ) % %! /\lop\p\pe%:=M%MPS%SVWXXXvw qB  EF  qF  qF5#47L#LPa"adg"gjklll  LM. .K)* .11J1JL6:*>?@%(.{   -{;<L 2 2 . .* 8euxyeyeye%CFV%VY\%\_`aaa  @A BW  Z[  B[  B[5#8;Y#Y]r"rux"x{|}}}  ab2 2K-. +.do.G.GL6:*>?@%%0.$A   Gf/I1.M%NOPI / / + +' 5bruvbvbve%@CS%SVY%Y\]^^^|} Qo  rs  Qs  Qs5#AD_#_  dB  #B  EH  #H  KL  M  M  M  yz4 4K/0   9 9L6:*>?@%(.{   -{;<; ! !  M 'TdghThThe]5E%E%KaPPPno }X  [\  }\  }\5#>#NRm"mps"svwxxx  bc+ +K' do77L6:*>?@%(.{   -|<=9    K %RbefRfRfe[3C%Cc%IANNNlm^kno^o^o5=;#>-"ORU"UXYZZZuv) )K% [kmnZnZne[;K-Kc-QTU&V&V&Vtu##&&]&]HZHZH\H\&]&]&]#]#]`cdo`p`p#p  !O  &k&7&7&9&9?X?Xbfggghjijhjk/ ~ ~t	?Q&&#**+|sTWAXAXA^A^A`A`+|+|jnoxjy+|+|+|}}} !!2!2!4!4:V:V`deeefhghfhiK* N Nt%))#**  ,MU]]SVX[E\E\EbEbEdEd  ,M  ,Mlpq}l~  ,M  ,M  ,M  N  N  N !%T_%>%>L6:*>?@%+9)6" "  *0	 	 	 -r232@ & & ! !" M,  !'	(:@X@X!Y!Y!Y  POOOO$$"75>22$0(/0B(C&),&7&7	& &      +(2244MMOO!.*(8/F056JA0N0N)4	$ $ $3!.$ $ $! !.  $:KLLL 	Y 	Y 	YLLJ#a&&JJKKK$1WXXXXXXXX	Ys#   X W.X 
Y.Y	Y	Yc                   &' 	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }nQ|d	k    r| |d
          z
  }n;|dk    r| |d          z
  }n%|dk    r| |d          z
  }n| |d          z
  }t	          | j                            ddd|iiiddddidddddgiddgiidddddgiddgiiddiddiddid ig                    }g }|D ]}	|	d!         }
|
dk    r|	d"         |
z  d#z  nd}d}t          |d$z  d%          d&z  }t          |
d'z  d%          d(z  }t          t          |	d)                   d*z  d%          d+z  }d}|		                    d,          r.|	d,         }|d-k    rd.}n|d/k    rd&}n|d0k    rd1}n|d2k    rd+}nd3}||z   |z   |z   }|d4k    rd5}n|d6k    rd7}n|d8k    rd9}n|d:k    rd;}nd<}| j
                            d=|	d=         iddddd>          }|r|                    t          |	d=                   |d?         |d@         |	                    dAdB          t          |d*          |t          |d*          |
t          |	d)                   t          |		                    d,d          d*          |	                    d          r|d                                         ndCdD           |r t!          dE |D                       t          |          z  }t          dF |D                       t          dG |D                       t          dH |D                       t          dI |D                       t          dJ |D                       dK}t          dL |D                       t          dM |D                       t          dN |D                       t          dO |D                       t          dP |D                       dQ}nd}i }i }g }t#          |dR dST          dCd%         }|rM|                    dUt          t!          dV |D                       t          |          z  d*                      dW |D             }|rPt!          dX |D                       t          |          z  }|                    dYt          |d*           dZ           t          |          dk    rcd[ |D             'd\ |D             &t          |          }t!          &'fd]t%          |          D                       }t!          '          }t!          &          }t!          d^ 'D                       }t!          d_ &D                       } ||z  ||z  z
  ||z  ||z  z
  || z  ||z  z
  z  d.z  z  }!t'          |!          d`k    r(|                    dat          |!d*           db           nbt'          |!          d.k    r(|                    dct          |!d*           db           n'|                    ddt          |!d*           db           g }"|	                    d;d          |	                    d<d          z   dk    r|"                    g de           |	                    dfd          dk    r|"                    g dg           t          |          dk    rNt!          dh |D                       t          di |D                       z  }#|#d0k    r|"                    dj           ||                                |                                t          |          t          |d*          |||||"|d6k    rdkndldmt+                      v rt          |          nddnt+                      v rt          |          nddodp}$dS|$dqS # t,          $ r9}%t.                              drt          |%                      ddsdcY dC}%~%S dC}%~%ww xY w)tz8Get user satisfaction and feedback analysis (admin only)Fra   r/   r   r
   r   rb   r.  r  r  r  rG  r  r  r  r7   r   rH  rI  rJ  r  r  r  r  failedr  rY  r  r  rK  rL  )r3   r  rH  failed_test_casesr"  r  rN  r  rH  r  r   rJ  皙?r   333333?r"  rx  皙?r  rM        ?i,  iX  g433333?i  皙?g      @Very Satisfiedg      @	Satisfiedg      @Neutralg      ?DissatisfiedVery Dissatisfiedr3   rY  r5   r-   r6   r+   N)r^   r5   r-   r6   rN  satisfaction_levelr  r  r  r  rZ  c              3   &   K   | ]}|d          V  dS rP  r   r  s     r)   r6  zBMongoHandler.get_user_satisfaction_and_feedback.<locals>.<genexpr>B  s(      *d*d$40D+E*d*d*d*d*d*dr   c                 *    g | ]}|d          dk    |S )r  r{  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>F  s)    *w*w*w1MaKbfvKvKv1KvKvKvr   c                 *    g | ]}|d          dk    |S )r  r|  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>G  s)    %m%m%mAaH\F]alFlFlaFlFlFlr   c                 *    g | ]}|d          dk    |S )r  r}  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>H  s)    #i#i#i!AFZD[_hDhDhADhDhDhr   c                 *    g | ]}|d          dk    |S )r  r~  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>I  s)    (s(s(sqK_I`drIrIrIrIrIrr   c                 *    g | ]}|d          dk    |S )r  r  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>J  s)    -}-}-}AaPdNei|N|N|aN|N|N|r   )r{  r|  r}  r~  r  c                 *    g | ]}|d          dk    |S r^  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>O  s*    /h/h/haPQR`PaegPgPgPgPgPgr   c                 >    g | ]}d |d         cxk    rdk     n n|S r`  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>P  re  r   c                 >    g | ]}d |d         cxk    rdk     n n|S rb  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>Q  sA    ,j,j,j1RSTUcSdMiMiMiMigiMiMiMiMiMiQMiMiMir   c                 >    g | ]}d |d         cxk    rdk     n n|S rd  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>R  sB    2p2p2pSUYZ[iYjSoSoSoSomoSoSoSoSoSo1SoSoSor   c                 *    g | ]}|d          dk     |S rg  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>S  s(    '_'_'_a.HY\^H^H^H^H^H^r   )zExcellent (90-100%)zGood (80-89%)zAverage (70-79%)zBelow Average (60-69%)Poor (<60%)c                     | d         S r\  r   r  s    r)   r  zAMongoHandler.get_user_satisfaction_and_feedback.<locals>.<lambda>^  s    QG[E\ r   Tr  z5Top performers have an average satisfaction score of c              3   &   K   | ]}|d          V  dS rP  r   rQ  s     r)   r6  zBMongoHandler.get_user_satisfaction_and_feedback.<locals>.<genexpr>`  sV        k\  k\  HIkl  nB  lC  k\  k\  k\  k\  k\  k\r   c                 &    g | ]}|d          dv |S )r  )r~  r  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>c  sJ      &H  &H  &HAaH\F]  bG  GG  GGa  GG  GG  GGr   c              3   &   K   | ]}|d          V  dS )r  Nr   rQ  s     r)   r6  zBMongoHandler.get_user_satisfaction_and_feedback.<locals>.<genexpr>e  s'      &Y&YQq'8&Y&Y&Y&Y&Y&Yr   z7Low satisfaction users have an average success rate of rU  c                     g | ]
}|d          S )r  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>j  s    !O!O!O!N"3!O!O!Or   c                     g | ]
}|d          S rU  r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>k  s    &Z&Z&Z1q)='>&Z&Z&Zr   c              3   :   K   | ]}|         |         z  V  d S Nr   )r   r   satisfaction_scoressuccess_scoress     r)   r6  zBMongoHandler.get_user_satisfaction_and_feedback.<locals>.<genexpr>o  s3      ZZA^A.1DQ1GGZZZZZZr   c              3       K   | ]	}||z  V  
d S r  r   )r   r  s     r)   r6  zBMongoHandler.get_user_satisfaction_and_feedback.<locals>.<genexpr>r  s&      ;;qQU;;;;;;r   c              3       K   | ]	}||z  V  
d S r  r   )r   ys     r)   r6  zBMongoHandler.get_user_satisfaction_and_feedback.<locals>.<genexpr>s  s&      @@qQU@@@@@@r   ffffff?zStrong correlation (z') between success rate and satisfactionzModerate correlation (zWeak correlation ()z7Focus on improving success rates for dissatisfied usersz1Provide additional training and support resourcesz)Implement user feedback collection systemr  )z(Investigate causes of high failure ratesz(Improve error handling and user guidancez&Consider simplifying complex workflowsc              3   >   K   | ]}|d          dk    |d          V  dS )r  r   Nr   rQ  s     r)   r6  zBMongoHandler.get_user_satisfaction_and_feedback.<locals>.<genexpr>  s:      )~)~qabcxay|}a}a}!,A*Ba}a}a}a})~)~r   c                 *    g | ]}|d          dk    |S )r  r   r   rQ  s     r)   rV  zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>  sd      FD  FD  FD  MN  gh  i~  g  BC  gC  gC  GH  gC  gC  gCr   z?Optimize test case generation process to reduce completion time	ImprovingzNeeds Attentiontop_performerslow_satisfaction_users)satisfaction_trendtop_performers_countimprovement_needed_count)r  r  r  ro  rm  rn  success_rate_distributionrp  feedback_insightsimprovement_recommendationsr1  )r0   satisfaction_analysisz.Error getting user satisfaction and feedback: z(Failed to retrieve satisfaction analysis)r_   r   r   rF   rf   r   r_  minr   rV   r   r>   r   r%   rD  rh   rs  r  rt  absr   localsr&   r   r$   )(r'   ri   r  r   r   r=  r  r  satisfaction_datar  total_casesr  rN  success_scoreactivity_scorediversity_scorecompletion_scoreavg_timer  ry  rm  rn  r  r  r  r  avg_success_ratensum_xysum_xsum_ysum_x2sum_y2correlationr  r  r  r(   r  r  s(                                         @@r)   "get_user_satisfaction_and_feedbackz/MongoHandler.get_user_satisfaction_and_feedback  s   X	]==// b#(5`aaa 54444444!(/##Ce## 99!#4#4#44

&& 991#5#5#55

'' 99"#5#5#55

&& 99##6#6#66

 99"#5#5#55
   9 9L6:*>?@%)/EI{3K+LaQR*S T. EIx3H+I1a*P Q* &1.$A,24F+G&,m%<  ; ! !  L$ !#+ D D)*<=]hkl]l]l,C D{ RUX X Xrs &'" !$L2$5q 9 9C ? "%[2%5q!9!9C!? #&c+n*E&F&F&JA"N"NQT"T $% ??#899 3*+@AH2~~+2((!S+2((!S+2((!T))+2((+2( &3^%Co%UXh%h" &,,)9&&'3..)4&&'3..)2&&'3..)7&&)<&  $4==ukRWFX>Y"#	\ \       %,,#&{5'9#:#: ,V 4!-g!6 , 0 0 @ @.34F.J.J.@(-lA(>(>,7-0^1L-M-M/4[__EZ\]5^5^`a/b/bP\P`P`amPnPn&xl<&@&J&J&L&L&Ltx. .    ! /'**d*dRc*d*d*d'd'dgjk|g}g}'}$ '**w*w6G*w*w*w&x&x!$%m%m1B%m%m%m!n!n"#i#i/@#i#i#ijj$'(s(s4E(s(s(s$t$t),-}-}9J-}-}-})~)~- -) ,//h/h;L/h/h/h+i+i%()g)g5F)g)g)g%h%h(+,j,j8I,j,j,j(k(k.12p2p>O2p2p2p.q.q#&'_'_3D'_'_'_#`#`- -)) ()$,.),.) !# $$5;\;\fjkkklnmnlnoN y!((  *xafgj  k\  k\  M[  k\  k\  k\  h\  h\  _b  cq  _r  _r  hr  tu  bv  bv  *x  *x  y  y  y &H  &H1B  &H  &H  &H"% B#&&Y&YBX&Y&Y&Y#Y#Y\_`v\w\w#w !((  *Achiy{|c}c}  *A  *A  *A  B  B  B $%%))!O!O=N!O!O!O&Z&ZHY&Z&Z&Z# )**ZZZZZQVWXQYQYZZZZZN++/00;;N;;;;;@@,?@@@@@ 6zEEM9q6zETYM?Y^_bh^hkpsxkx^x>y  B  >B  B{##c))%,,  .CE+WXDYDY  .C  .C  .C  D  D  D  D%%++%,,  .EeKYZF[F[  .E  .E  .E  F  F  F  F%,,  .A%UVBWBW  .A  .A  .A  B  B  B +-'(,,^Q??B[B_B_`suvBwBwwz{{{+22 4 4 4    ),,]A>>BB+22 4 4 4    $%%))&))~)~L])~)~)~&~&~  BE  FD  FD  Rc  FD  FD  FD  BE  BE  'E#&,,/667xyyy  +(2244MMOO(+,=(>(>(-.BA(F(F-F-F->%6/J9MPS9S9S++YjCSW]W_W_C_C_C,?,?,?efOgkqksksOsOs4J0K0K0Kyz % %!$  $>STTT 	] 	] 	]LLR#a&&RRSSS$1[\\\\\\\\	]s#   _ ^(_ 
`
.`?`
`
c                 
   	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }nQ|d	k    r| |d
          z
  }n;|dk    r| |d          z
  }n%|dk    r| |d          z
  }n| |d          z
  }t	          | j                            ddd|iiidddddddiddiddiddididddiig                    }g }g }	g }
g }|D ]p}|d          }| j                            d |idddddd!          }|r?|d         }|d"         }|d#         }|r|r||z
  j	        }|dk    r||z  }n|}nd}|r
||z
  j	        nd}| 
                    ||||d$                   }|                     |          }t          |          |d%         |d&         |                    d'd(          |||d)         |d*         |d+         d,	}|                    |           |d)         d-k    r|	                    |           ,|d*         d.k    r|
                    |           O|d+         d/k    r|                    |           r|rt          d0 |D                       t!          |          z  }t          d1 |D                       t!          |          z  }t          d2 |D                       t!          |          z  }t!          d3 |D                       }t!          d4 |D                       }t!          d5 |D                       }ndx}x}}dx}x}}g }|d6k    r*|                    d7t#          |d8z  d           d9           |d-k    r*|                    d:t#          |d8z  d           d;           |d<k     r*|                    d=t#          |d8z  d           d>           |dk    r|                    | d?           |dk    r|                    | d@           g }|	r|                    g dA           |
r|                    g dB           |r|                    g dC           |                     ||          } ||                                |                                t!          |          t#          |dD          t#          |dD          t#          |dD          |||dE||	|
|dF||| |d6k    rdGn	|dHk    rdIndJ|d-k    rdGn	|d<k    rdIndJ|d6k    rdKn	|d/k    rdLndMdNdO}!dP|!dQS # t*          $ r9}"t,                              dRt          |"                      ddSdcY dT}"~"S dT}"~"ww xY w)Uz*Get user predictive analytics (admin only)Fra   r/   r   r
   r   rb   r.  r  r  r  rG  r  r  r  r7   r   rH  rI  r  rL  rY  r  )r;  r   rd   rJ  r7  rK  )r3   
activitiesr~  r  rN  rX  r~  r   r3   )r5   r-   r6   r7   r8   r  rN  r  r5   r-   r6   r+   
churn_riskgrowth_potentialr  )	r^   r5   r-   r6   predictionsuser_category
risk_scorer  r  r  皙?rv  c              3   &   K   | ]}|d          V  dS )r  Nr   rQ  s     r)   r6  z=MongoHandler.get_user_predictive_analytics.<locals>.<genexpr>  s&      $O$OQ|_$O$O$O$O$O$Or   c              3   &   K   | ]}|d          V  dS )r  Nr   rQ  s     r)   r6  z=MongoHandler.get_user_predictive_analytics.<locals>.<genexpr>  (      *[*[Q1-?+@*[*[*[*[*[*[r   c              3   &   K   | ]}|d          V  dS )r  Nr   rQ  s     r)   r6  z=MongoHandler.get_user_predictive_analytics.<locals>.<genexpr>   r  r   c                 *    g | ]}|d          dk    |S )r  r  r   rQ  s     r)   rV  z>MongoHandler.get_user_predictive_analytics.<locals>.<listcomp>#  s'    &]&]&]QaoY\F\F\qF\F\F\r   c                 *    g | ]}|d          dk    |S )r  r  r   rQ  s     r)   rV  z>MongoHandler.get_user_predictive_analytics.<locals>.<listcomp>$  )    +h+h+h!1M_K`dgKgKgAKgKgKgr   c                 *    g | ]}|d          dk    |S )r  rv  r   rQ  s     r)   rV  z>MongoHandler.get_user_predictive_analytics.<locals>.<listcomp>%  r  r   333333?zHigh overall churn risk (r  z#%) - implement retention strategieszStrong growth potential (z%%) - focus on expansion opportunitiesry  zLow engagement levels (z#%) - implement engagement campaignsz8 users at high churn risk - prioritize retention effortsz6 users with high growth potential - focus on expansion)z:Implement targeted retention campaigns for high-risk usersz+Provide personalized support and incentivesz.Analyze common patterns among churn-risk users)zCOffer advanced features and premium options to high-potential usersz1Provide upselling and cross-selling opportunitiesz'Create loyalty programs for power users)z4Send re-engagement campaigns to low-engagement usersz-Provide onboarding improvements and tutorialszImplement gamification elementsrz  )average_churn_riskaverage_growth_potentialaverage_engagement_scorehigh_risk_usershigh_potential_userslow_engagement_users)churn_risk_usersgrowth_potential_usersengagement_opportunitiesr  rw  r  r  GoodFairPoor)overall_risk_levelgrowth_opportunityengagement_status)r  r  r  ro  predictive_metricsuser_predictionsuser_categoriespredictive_insightsaction_recommendationspredictive_trendsr1  T)r0   predictive_analyticsz)Error getting user predictive analytics: z'Failed to retrieve predictive analyticsN)r_   r   r   rF   rf   r   r_  r   r>   r/  _predict_user_behavior_categorize_user_for_predictionr%   rV   r   rs  r   rD  r   _calculate_predictive_trendsrh   r&   r   r$   )#r'   ri   r  r   r   r=  r  user_activity_patternsr  r  r  r  r  r^   ry  r~  r  rN  activity_perioddaily_activity_ratedays_since_last_activityr  r  user_predictionavg_churn_riskavg_growth_potentialavg_engagement_scorer  r  r  r  r  r  r  r(   s#                                      r)   get_user_predictive_analyticsz*MongoHandler.get_user_predictive_analytics  sP   J	\==// b#(5`aaa 54444444!(/##Ce## 99!#4#4#44

&& 991#5#5#55

'' 99"#5#5#55

&& 99##6#6#66

 99"#5#5#55
 &*$/*C*CL6:*>?@%)6+9&/" "# *0'-}&=&,m%<   -r23E + + & &"&  "!%'"')$ 6 ?I ?I&u-  $4==ug>N"#"#Q Q       3I'34F'G$%12B%CN$0$AM & 0- 0+8>+I*O*Q..2B_2T//2B//./+ N[/am0C/I/I`a, #'"="=(+0$\2	# #K %)$H$H$U$UM $'w<< ,V 4!-g!6 , 0 0 @ @'2)6&1,&?,78J,K,78J,K
' 
'O %++O<<< #<0C77(//@@@@$%78C??.55oFFFF$%78C??077HHH   R!$$O$O>N$O$O$O!O!ORUVfRgRg!g'**[*[JZ*[*[*['['[^abr^s^s's$'**[*[JZ*[*[*['['[^abr^s^s's$ #&&]&]2B&]&]&]"^"^'*+h+h7G+h+h+h'i'i$'*+h+h7G+h+h+h'i'i$$OPPP!58LPQQQ"69M #%###**  ,Ku^^aMacdGeGe  ,K  ,K  ,K  L  L  L#c))#**  ,SuMadgMgijGkGk  ,S  ,S  ,S  T  T  T#c))#**  ,OUK_beKeghEiEi  ,O  ,O  ,O  P  P  P""#**o+w+w+wxxx#a''#**.B+z+z+z{{{ &(" &-- / / /    & &-- / / /    ( &-- / / /    !% A ABRT_ ` `  +(2244MMOO(+,<(=(=*/*B*B056JA0N0N056JA0N0N'6,@,@' ' %5(8.D0H$ $
 (;*@%64BS4H4H&&ZhknZnZnhhty4H34N4N&&`twz`z`zT\T\  AF3G#3M3M]qtw]w]wSYSY  ~D -$ $ :  $=QRRR 	\ 	\ 	\LLMSVVMMNNN$1Z[[[[[[[[	\s#   T S4T 
U.U	UUc                    d}|dk    r|dz  }n#|dk    r|dz  }n|dk    r|dz  }n|dk    r|d	z  }|d	k     r|dz  }n|d
k     r|dz  }n|dk     r|d	z  }|dk     r|dz  }n|dk     r|d	z  }t          |          dk    rd |D             }|                                 g }t          dt          |                    D ]0}||         ||dz
           z
  j        }	|                    |	           1|r*t          |          t          |          z  }
|
dk    r|d	z  }d}|dk    r|dz  }n#|dk    r|dz  }n|d
k    r|dz  }n|d	k    r|d	z  }|dk    r|dz  }n|dk    r|dz  }n|dk    r|d	z  }t          d |D                       }t          |          dk    r|dz  }nt          |          dk    r|d	z  }|dk    r|d	z  }d}|dk    r|dz  }n#|d
k    r|dz  }n|dk    r|dz  }n|d	k    r|d	z  }|dk    r|dz  }n|dk    r|dz  }n|dk    r|d	z  }|dk    r|dz  }n|dk    r|d	z  }t          |          dk    r|d	z  }t          |d          t          |d          t          |d          dS )z&Helper method to predict user behaviorr   rG  rv     rw  r?  rx  rz  rz  ry        ?rJ  r   rb   c                     g | ]
}|d          S )r;  r   r   as     r)   rV  z7MongoHandler._predict_user_behavior.<locals>.<listcomp>  s    ===Q!K.===r   rx  r   c              3   &   K   | ]}|d          V  dS r   Nr   r  s     r)   r6  z6MongoHandler._predict_user_behavior.<locals>.<genexpr>  s'      @@1]+@@@@@@r   )r  r  r  )r   r   rt  r/  r   rs  setr  )r'   r~  r  r  r  r  
timestampsgapsr   gapavg_gapr  r"  r  s                 r)   r  z#MongoHandler._predict_user_behaviorz  s    
 $b((#JJ%**#JJ%))#JJ%))#J $$#JJ 3&&#JJ 3&&#J a#JJ""#J z??Q==*===JOOD1c*oo.. ! !!!}z!A#6<C     &d))c$ii/Q;;#%J  !### A%%# C''# C''# r!!####""# @@Z@@@@@|!!#!### $q((#  !### C''# C''# C''# $q((#%**#%**# r!!#""# |!!# j#.. #$4c : : #$4c : :
 
 	
r   c                     |d         }|d         }|d         }|dk    rdS |dk    rdS |dk    rd	S |dk    r|d
k    rdS |dk    rdS dS )z6Helper method to categorize users based on predictionsr  r  r  r  zHigh Churn Riskr  zHigh Growth Potentialrw  zLow Engagementr  z
Power Userry  zEngaged UserzStandard Userr   )r'   r  r  r  r  s        r)   r  z,MongoHandler._categorize_user_for_prediction  s     .
&'9:&'9:$$$$**$$##$$)9S)@)@<$$!>"?r   c                    |si S i }|D ]#}|d         }||vrd||<   ||xx         dz  cc<   $t          |          }i }|                                D ]\  }}t          ||z  dz  d          ||<   g }	t          |                                d d          D ]&\  }}
|
d	k    r|	                    | d
|
 d           '|||	t          |          dS )z,Helper method to calculate predictive trendsr  r   rb   r  rx  c                     | d         S r#  r   r  s    r)   r  z;MongoHandler._calculate_predictive_trends.<locals>.<lambda>  s    WXYZW[ r   Tr  r   r{   z
% of users)category_distributioncategory_percentagesdominant_trendstotal_categories)r   r   rD  r  r   )r'   r  r  category_countsr+   categoryr   r  r   r  r  s              r)   r  z)MongoHandler._calculate_predictive_trends  sO    	I $ 	+ 	+DO,H..,-)H%%%*%%%% *++!.4466 	S 	SOHe-2EK4G33NPQ-R-R ** $*+?+E+E+G+G^^ei$j$j$j 	N 	N HjR&&('L'Lj'L'L'LMMM &5$8. #O 4 4	
 
 	
r   c                    	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }ng|d	k    r| |d
          z
  }nQ|dk    r| |d          z
  }n;|dk    r| |d          z
  }n%|dk    r| |d          z
  }n| |d          z
  }i }|                     |          }|d         r|d         |d<   |                     ||          }	|	d         r|	d         |d<   |                     ||          }
|
d         r|
d         |d<   |                     ||          }|d         r||d<   |                     ||          }|d         r|d         |d<   | 	                    ||          }|d         r|d         |d<   | 
                    ||          }|d         r|d         |d<   |                     ||          }|d         r|d         |d<   |                     ||          }|d         r|d         |d<   |                     ||          }|d         r|d         |d<   |                     ||          }|d         r|d         |d<   |                     |          }|d         r|d         |d<   |                     |          }|d         r|d          |d!<   |                     ||          }|                     |          }|                     |          }|                     |          }||                                |                                |||||t-          |          |                     |          |                                t-          |          t-          |          d"d#	}d$|d%S # t0          $ r9}t2                              d&t7          |                      dd'dcY d(}~S d(}~ww xY w))zCGet comprehensive user analytics combining all metrics (admin only)Fra   r/   r   r
   r   rb   r.  r  r?  r  rG  r}  r  r  r  r0   r   r  r)  rB  )r  performance_metricsr  r5  rg  r  r  r  r  r  r  r  )total_metrics_analyzeddata_completenessanalysis_timestamprecommendations_countinsights_count)	r  r  r  overall_health_scoreexecutive_summarykey_insightsstrategic_recommendationsanalytics_datar1  T)r0   comprehensive_analyticsz,Error getting comprehensive user analytics: z*Failed to retrieve comprehensive analyticsN)r_   r   r   rF   r   r4  rF  r  r  r=  rr  r  r  r  r  r  r  _generate_executive_summary_generate_key_insights#_generate_strategic_recommendations_calculate_overall_health_scorerh   r   _calculate_data_completenessr&   r   r$   r%   )r'   ri   r  r   r   r=  r  r  r  r)  rB  r  r  r5  rg  r  r  r  r  r  r  r  r  r  r
  r  r(   s                              r)    get_comprehensive_user_analyticsz-MongoHandler.get_comprehensive_user_analytics  s8   |	_==// b#(5`aaa 54444444!(/##Ce## 99!#4#4#44

&& 99!#4#4#44

'' 99"#5#5#55

	)) 99"#5#5#55

&& 99##6#6#66

 99"#5#5#55
  N 11-@@J)$ M4>|4L01  $==m[YY	* Z5EFX5Y12 "&!A!A-Q\!]!]!), `7IJ^7_34 #'"C"CM_j"C"k"k"9- L8K45 !% ? ?{ [ [ + ]6GH[6\23 %)$G$GWb$c$c!$Y/ i:OPg:h67 !% ? ?{ [ [ + ]6GH[6\23 "&!A!A-Q\!]!]!), `7IJ^7_34 !77{SSMY' Q2?2P/ %)$K$KM[f$g$g!$Y/ i:OPg:h67 $(#E#EmU`#a#a #I. f9MNd9e56 #66}EEOy) W4CDU4V01 !99-HHMY' Q2?2P/ !% @ @Q\ ] ]  66~FFL )-(P(PQ_(`(`% $(#G#G#W#W   +(2244MMOO(<%6 ,-F"0.1..A.A)-)J)J>)Z)Z*---//-01J-K-K&),&7&7 ' '#$  $@WXXX 	_ 	_ 	_LLPAPPQQQ$1]^^^^^^^^	_s#   N M>N 
O%.OOOc           	         d| dg i g g g d}d|v rk|d         }|d                              d|                    dd           d	|                    d
d           d|                    dd           g           d|v r8|d         }|                    dd          |                    d|          d|d<   d|v rT|d         }|d                              d|                    dd           d|                    dd           dg           d|v rP|d         }|                    di                               dd          }|d                             d|            d|v rU|d         }	|d                              d |	                    d!d           dd"|	                    d#d           dg           |S )$z.Generate executive summary from analytics dataz(Comprehensive user analytics report for z period)overviewkey_highlightsperformance_overviewr  risksopportunitiesr  r  zTotal users: r   r   zActive users: r   zNew users this month: r   r  r  )ro  r  r  r  r  zTotal new users: r  zAverage growth rate: r  rU  r  r1  r  r  r  zOverall churn risk level: rB  r  zEngagement rate: r<  zActivity rate: r=  )r   rV   r   )
r'   r  r  r1  r   perfr  pred
risk_level
engagements
             r)   r  z(MongoHandler._generate_executive_summary  sI    X;WWW $&
 
 .."#45E$%,,=		- ; ;==?>1!=!=??O3I1)M)MOO.    !N22!"78D(,(B(B#xx{CC/ /G*+ n,,#O4FH$$FFJJ/@!$D$DFFO

3H!(L(LOOO&    "^33!"89D)R00445I9UUJG##$M$M$MNNN  >11'(<=JO$++KJNN3Da$H$HKKKG*..!"D"DGGG-   
 r   c                    g }d|v rA|d         }|                     dd          dk    r|                    d|d          d           d|v r7|d         }|                     dd          dk     r|                    d	           d
|v rK|d
         }|                     di                                dd          dk     r|                    d           d|v rx|d         }|                     d          r[t          d |d         D                       t          |d                   z  }|                    dt	          |d                      |S )z)Generate key insights from analytics datar  r  r   zUser growth is positive with z
 new usersrB  r<  r   zGUser engagement is below optimal levels - consider engagement campaignsr  r  r  rL  z<First-week retention needs improvement - focus on onboardingr  r  c              3   &   K   | ]}|d          V  dS r  r   rQ  s     r)   r6  z6MongoHandler._generate_key_insights.<locals>.<genexpr>  s(      $Y$YqQ'9%:$Y$Y$Y$Y$Y$Yr   Average test cases per user: rb   )rV   r   rs  r   rD  )r'   r  insightsr  r  	retentionr  r  s           r)   r  z#MongoHandler._generate_key_insights  s    n,,#O4Fzz+Q//!33 eGX@Y e e efff  >11'(<=J~~/33b88 ijjj  >11&';<I}}8"==AABTVWXX[]]] ^___ !N22!"78Dxx'' \!$$Y$YDDX$Y$Y$Y!Y!Y\_`des`t\u\u!u ZnVW@X@X Z Z[[[r   c                    g }d|v r7|d         }|                     dd          dk     r|                    d           d|v rK|d         }|                     di                                dd          d	k     r|                    d
           d|v r7|d         }|                     dd          dk     r|                    d           d|v rm|d         }|                     d          rPd |d         D             }t          |          t          |d                   dz  k    r|                    d           d|v r6|d         }|                     d          dk    r|                    d           |S )z6Generate strategic recommendations from analytics datar  r  r   r   z:Implement user acquisition strategies to increase sign-upsr  r  r  rG  z;Develop long-term retention strategies and loyalty programsrB  r<  rM  zCImplement user engagement campaigns and feature adoption strategiesr  r  c                 *    g | ]}|d          dk     |S )r  rJ  r   rQ  s     r)   rV  zDMongoHandler._generate_strategic_recommendations.<locals>.<listcomp>  s)    !_!_!_QGYEZ]^E^E^!E^E^E^r   rw  z@Provide additional support and training for low-performing usersr  r8  r+  z7Address system health issues to improve user experience)rV   r   r   )	r'   r  r	  r  r$  r  r  low_performershealths	            r)   r  z0MongoHandler._generate_strategic_recommendations  s    n,,#O4Fzz+Q//"44&&'cddd  >11&';<I}}8"==AABTVWXX[]]]&&'deee  >11'(<=J~~/33b88&&'lmmm !N22!"78Dxx'' o!_!_T.-A!_!_!_~&&T.-A)B)BS)HHH#**+mnnn n,,#O4Fzz*++{::&&'`aaar   c                    d}d}d|v r<|d         }t          |                    dd          dz  d          }||dz  z  }|dz  }d|v r<|d         }t          |                    dd          d	z  d          }||dz  z  }|dz  }d
|v rP|d
         }t          |                    di                               dd          d	z  d          }	||	dz  z  }|dz  }d|v r2|d         }
|
                    d          dk    rdnd}||dz  z  }|dz  }|dk    r||z  }nd}t          |d	z  d          }|dk    rd}n|dk    rd}n|dk    rd}nd}|||dS )z9Calculate overall system health score from analytics datar   r  r  r   r  g      ?rB  r<  r  r  r  r  r  r8  r  ry  rb   r
  	ExcellentrM  r  (   r  r  )scorer  factors_analyzed)r  rV   rD  )r'   r  health_scoretotal_factorsr  growth_scorer  r  r$  retention_scorer(  system_scorefinal_scorehealth_percentagehealth_categorys                  r)   r  z,MongoHandler._calculate_overall_health_score  s    n,,#O4Fvzz*;Q??"DcJJLL4//LT!M  >11'(<=J":>>2CQ#G#G##MsSS,t33LT!M  >11&';<I!)--0KR"P"P"T"TUgij"k"knq"qsvwwOOd22LT!M n,,#O4F"(**-=">">)"K"K33QTLL4//LT!M 1&6KKK "+"3Q77"")OO"$$$OO"$$$OO$O '' -
 
 	
r   c                     d}t          |          }t          ||z  dz  d          }|dk    rd}n|dk    rd}n|dk    rd	}nd
}||||dS )z&Calculate data completeness percentage   r  rb   r  r*  K   r  rM  r  r  )r  ru  available_metricstotal_possible_metrics)r   rD  )r'   r  r:  r9  completeness_percentagecompleteness_levels         r)   r  z)MongoHandler._calculate_data_completenessQ  s    !#//"'):=S)SWZ(Z\]"^"^"b((!,$**!'$**!'!' 2'!2&<	
 
 	
r   c                    	 | j                             ddi          }|rdddS t          t          j                              |                                t          j        |                    d          t          j	                              |dt          j                    dddddddddddddd	d
	}| j                             |          }|j        rit                              d|            |                     ddt          |j                  d| d           ddt          |j                  ||dddS dddS # t"          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)zGCreate the initial admin user (should only be called once during setup)r6   rN   Fz7Admin user already exists. Cannot create another admin.r/   r2   NTr  )	r3   r-   r4   r5   r6   r7   r8   r9   r  z)Initial admin user created successfully: SYSTEM_SETUPinitial_admin_createdzInitial admin user z created during system setup)ri   r  r  r  z'Initial admin user created successfullyr;   )r0   r1   
admin_userrO   z#Error creating initial admin user: )r   r>   r%   rD   rE   r?   r@   rB   rC   rA   r   rF   rG   r   r   r   r  r&   r$   )r'   r-   r4   r5   rP   admin_user_docrQ   r(   s           r)   create_initial_admin_userz&MongoHandler.create_initial_admin_userh  s   <	P!2;;VW<MNNN p#(5nooo 4:<<(("M(//'*B*BFNDTDTUU&o//"!(,(,-1*.-1'+(,'+)-*.-1    N2 *55nEEF! TOOOPPP %%"0 7!&"455U%UUU	 &     $H!&"455!& $ '	# #	 	 	 $)5RSSS 	P 	P 	PLLGs1vvGGHHH$1NOOOOOOOO	Ps)   "E DE ?E 
F.F<FFc                 l   	 | j                             d|i          }|sdddS t          | j                            d|idddddd                              dd	                              d
                    }|D ]?}d|v rt          |d                   |d<   d|v r|d                                         |d<   @|	                    dd          }| 
                    |          }t          |          }t          d |D                       }d}	|r|d         }	t          |d                   |d         |d         ||	                    d          r|d                                         nd|	                    d          r|d                                         ndd|||	d||d         r|	                    di           ni |d}
|dk    r|                     |          }||
d<   d|
dS # t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)r   r3   Fr   r/   r^   rb   r   r7   r   r   r6   r+   c                     g | ]Q}|                     d d                              t          j                                        d                    O|RS )r7   r  r|  )rV   
startswithr   rF   r+  r   tcs     r)   rV  z8MongoHandler.get_user_dashboard_data.<locals>.<listcomp>  s      )S  )S  )SP\^`IaIaIlIlmum|m~m~  nH  nH  IP  nQ  nQ  JR  JR  )S  )S  )S  )Sr   Nr   r5   r-   r8   r   r   r0   r  )r  r   r   r  r6   rN   
admin_dataTr  r
  r  )r   r>   rf   r   rg   r   r   r%   rh   rV   r  r   _get_admin_dashboard_datar&   r   r$   )r'   r^   r+   r  r  r6   r  r  this_month_test_casesr  r	  rH  r(   s                r)   r  z$MongoHandler.get_user_dashboard_data  s   <	V(115'2BCCD G#(5EFFF #4?#7#7G$AQqTUVV$ $ d<$$UU2YY0 0O - R R	I%%'*9U+;'<'<Ie$9,,.7.E.O.O.Q.QIl+ 88FF++D33G<<K  #?33$'  )S  )So  )S  )S  )S  %T  %T! "N 4!0!3
 d5k** L!'] DHHH\DZDZ"d$|"4">">"@"@"@`dDHHH\DZDZ"d$|"4">">"@"@"@`d  )9"7&4 
 .EPQZE[c{}bAAAac! N( w!;;GDD
/9|,#~FFF 	V 	V 	VLLGs1vvGGHHH$1TUUUUUUUU	Vs#   "G0 G
G0 0
H3:.H.(H3.H3c                 <   	 |                      |          }|                     |          }|                     |d          }|                     |          }|d         r|                    di           ni |d         r|                    di           ni |d         r|                    dg           ng |d         r|                    di           ni g dd}|S # t
          $ r6}t                              d	t          |                      i cY d
}~S d
}~ww xY w)z!Get admin-specific dashboard datar  r0   r  r   r)  r  )zView all userszSystem health checkzUser analyticszBackup datazExport reports)r  r  r  r  quick_actionsz$Error getting admin dashboard data: N)	r  r   r4  r  rV   r&   r   r$   r%   )r'   ri   r  r  r  r  rH  r(   s           r)   rI  z&MongoHandler._get_admin_dashboard_data  sa   	"66}EEO 11-@@J #<<]FSSO !99-HHM RaajQk#s?#6#67H"#M#M#MqsGQR[G\#d:>>,#C#C#CbdRabkRl#t?#6#67I2#N#N#NrtKXYbKc!k!2!2?B!G!G!Gik" " " J  	 	 	LLHAHHIIIIIIIII	s   CC 
D%+DDDc                 .   	 ddl m }m}  |j                    }|dk    r| |d          z
  }ng|dk    r| |d          z
  }nQ|dk    r| |d	          z
  }n;|d
k    r| |d          z
  }n%|dk    r| |d          z
  }n| |d	          z
  }t          | j                            |d|iddddddd                              dd                    }| j                            d|iddd          }g }	|r6|	                    d          r!|	
                    d|d         dddd           |D ]z}
|	
                    d|
d         d|
	                    dd           ddt          |
d                   |
	                    dd          |
	                    d d!          d"d#           {|r6|	                    d$          r!|	
                    d%|d$         d&d'dd           |	                    d( d)*           |	D ]}|d+                                         |d+<    i }|	D ]6}|d+         d,d-         }||vrg ||<   ||         
                    |           7t          |	          }t          d. |	D                       }t          d/ |	D                       }t          |	          dk    rit          |	d0 1          }t          |	d2 1          } |j        |d+                   } |j        |d+                   }||z
  j        }|dk    r||z  }n|}n|}|||t%          |d3          |r*t          |                                d4 1          d         nd,|                     |	          d5}||                                |                                ||	||||k    rdnd6|                     |          |dk    rd7nd8d9d:}d)|d;S # t,          $ r9}t.                              d<t          |                      d=d>d?cY d,}~S d,}~ww xY w)@z/Get user activity timeline with detailed eventsr   r
   r   rb   r.  r  r  r  rG  r}  r  r  r  r   r   )r3   r7   r   rd   r   r7   r   r3   rO  user_registrationzUser account createdz	user-plusaccount)
event_typer;  descriptioniconr  test_case_generatedzGenerated test case from r   unknownzfile-earmark-textr  r   Untitled)test_case_idr   r   )rP  r;  rQ  rR  r  r  r8   
user_loginzUser logged inzbox-arrow-in-rightc                     | d         S rY  r   r  s    r)   r  z9MongoHandler.get_user_activity_timeline.<locals>.<lambda>R  s
    q~ r   Tr  r;  Nr   c                 *    g | ]}|d          dk    |S )rP  rS  r   r   r(   s     r)   rV  z;MongoHandler.get_user_activity_timeline.<locals>.<listcomp>b  s'    #k#k#k!!L/UjBjBjABjBjBjr   c                 &    g | ]}|d          dv |S )rP  )rN  rW  r   rZ  s     r)   rV  z;MongoHandler.get_user_activity_timeline.<locals>.<listcomp>c  s'    !w!w!w,Sv@v@v!@v@v@vr   c                     | d         S rY  r   r  s    r)   r  z9MongoHandler.get_user_activity_timeline.<locals>.<lambda>h  s
    ; r   r(  c                     | d         S rY  r   r  s    r)   r  z9MongoHandler.get_user_activity_timeline.<locals>.<lambda>i  s
    + r   rx  c                 ,    t          | d                   S r#  )r   r  s    r)   r  z9MongoHandler.get_user_activity_timeline.<locals>.<lambda>|  s    SQRSTQUYY r   )total_eventstest_case_eventsaccount_eventsevents_per_daymost_active_dayactivity_streakaccount_activityCompletezNo activity)most_common_eventr%  timeline_completeness)r  r  r  r_  timeline_eventsevents_by_dater)  r1  )r0   timeline_dataz&Error getting user activity timeline: Fz$Failed to retrieve activity timeliner/   )r   r   rF   rf   r   rg   r   r   r>   rV   r   r%   rh   r   r  r  r  r/  rD  r   _calculate_activity_streakr7  r&   r   r$   )r'   r^   r  r   r   r=  r  test_case_activitiesr+   ri  rb  eventrj  date_keyr_  r`  ra  first_event
last_event
first_date	last_datedays_betweenrb  r)  rk  r(   s                             r)   get_user_activity_timelinez'MongoHandler.get_user_activity_timeline  s   F	Y44444444!(/##Ce## 99!#4#4#44

&& 991#5#5#55

'' 99"#5#5#55

	)) 99"#5#5#55

&& 99##6#6#66

 99"#5#5#55
 $((<(<#FJ3GHH1TUVV) ) d<$$$& $&  (115'2BE E  D !O  .. &&"5!%l!3#9' )( (    1  &&"7!),!7#gx||M[d?e?e#g#g/ +(+HUO(<(<'/||M9'M'M!)gz!B!B   ( (      .. &&".!%l!3#30 )( (      %=%=t LLL ) D D%*;%7%A%A%C%Ck""  N( 7 7 -crc2>11/1N8,x(//6666 //L"#k#k#k#k#kll !w!w_!w!w!wxxN ?##a''!/7O7OPPP 6N6NOOO
3X3K4LMM
2H2:k3JKK	 )J 6<!##%1L%@NN%1NN!- !-$4"0"'":":^l#v3~';';'='=CVCV#W#W#WXY#Z#Zrv#'#B#B?#S#S     +(2244MMOO ,#2"0$4BRUcBcBc)>)>i{&*&J&J>&Z&Z;G!;K;KZZQ^  M  $mDDD 	Y 	Y 	YLLJ#a&&JJKKK$1WXXXXXXXX	Ys   OO 
P.P	PPc                    |sdS t          |d           }d}d}d}|D ][}t          j        |d                                                   }|d}n&||z
  j        dk    r|dz  }nt          ||          }d}|}\t          ||          }|S )z Calculate user's activity streakr   c                     | d         S rY  r   r  s    r)   r  z9MongoHandler._calculate_activity_streak.<locals>.<lambda>  s
    an r   r(  Nr;  rb   )r  r   r  r  r/  r  )r'   ri  sorted_eventscurrent_streak
max_streaklast_event_datern  
event_dates           r)   rl  z'MongoHandler._calculate_activity_streak  s     	1 4L4LMMM
" 	) 	)E!/k0BCCHHJJJ&!".499!# ^<<
!"(OO ^44
r   c                 f   	 t          | j                            d|iddddd                              dd                    }| j                            d|iddd          }|sddd	S g }g }t          |          dk    r=|d
         }|                    ddddd|d                                         dd           t          |          dk    r=|d         }|                    ddddd|d                                         dd           t          |          dk    r=|d         }|                    ddddd|d                                         dd           t          |          dk    r=|d         }	|                    dd d!dd|	d                                         d"d           t          d# |D                       }
t          |
          d$k    rP|                    d%d&d't          |
           d(d)d*|r |d+         d                                         nd,d-d           h d.}|

                    |          r?|                    d/d0d1d2d*|r |d+         d                                         nd,d3d           |                    d          rt          j                    |d         z
  j        }|d4k    rF|                    d5d6d7d8d9|d         t          d4:          z                                   dd           |d;k    rF|                    d<d=d>d8d9|d         t          d;:          z                                   d-d           |d?k    rF|                    d@dAdBd8d9|d         t          d?:          z                                   dd           |rBt                      }|D ]/}|                    |d                                                    0t%          |          }d
}d
}t'          t          |                    D ]@}|d
k    rd}||         ||dz
           z
  j        dk    r|dz  }.t)          ||          }d}At)          ||          }|dCk    r;|                    dDdEdFdGdH|d+         d                                         d-d           |d4k    r;|                    dIdJdKdGdH|d+         d                                         dd           g }t          |          }|dk     r#|                    dL|dddM|dz  dz  dN           nQ|dk     r#|                    dL|dddO|dz  dz  dN           n(|dk     r"|                    dL|dd dP|dz  dz  dN           t          |
          dQk     r<|                    dRt          |
          dQd0dSt          |
          dQz  dz  dN           t          |          }i }i }|D ]D}|dT         }||vrd
||<   ||xx         dz  cc<   |dU         }||vrd
||<   ||xx         dz  cc<   EdV}||z  dz  }|t+          |d          |||||dW|                     |          |r|d
         nd,|r|d
         nd,dXdY}dZ|d[S # t.          $ r9}t0                              d\t5          |                      dd]d	cY d,}~S d,}~ww xY w)^z<Get user achievements and milestones based on their activityr^   rb   r3   r7   r   rd   r7   r3   rO  Fr   r/   r   rF  zFirst StepszGenerated your first test casez	star-fill	milestonecommon)r<   r   rQ  rR  r  unlocked_atrarityr   	   ten_test_caseszGetting StartedzGenerated 10 test casesr   1   fifty_test_caseszTest Case MasterzGenerated 50 test casesrarer  c   hundred_test_caseszTest Case ExpertzGenerated 100 test casesepicc              3   P   K   | ]!}|                     d           |d          V  "dS r  rV   rF  s     r)   r6  zDMongoHandler.get_user_achievements_and_milestones.<locals>.<genexpr>  s9      __RP]I^I^_r-0______r   rx  multiple_sourceszVersatile TesterzUsed z different source typesr   versatilityr   Nuncommon>   urljiratextazureimageall_sourceszSource MasterzUsed all available source typesaward	legendaryrG  monthly_userzMonthly Userz$Been using the platform for 30+ dayszcalendar-checkloyaltyr.  r  quarterly_userzQuarterly Userz$Been using the platform for 90+ daysr  yearly_userzYearly Userz%Been using the platform for 365+ daysr?  weekly_streakzWeekly Warriorz"Maintained a 7-day activity streakfireconsistencymonthly_streakzMonthly Masterz#Maintained a 30-day activity streakr   zGenerate 10 test cases)r  currenttargetr   rQ  progresszGenerate 50 test caseszGenerate 100 test casesrJ  r"  zUse all 5 source typesr  r     )by_category	by_raritytotal_possible)ru  next_achievementrecent_achievement)total_achievementscompletion_percentageachievementsnext_milestonesr   r1  T)r0   achievements_dataz!Error getting user achievements: zFailed to retrieve achievements)rf   r   rg   r   r   r>   r   r   rh   r  
issupersetrV   r   rF   r/  r   addr  r  rt  r  rD  _get_achievement_levelr&   r   r$   r%   )r'   r^   r   r+   r  
milestonesrF  tenth_test_casefiftieth_test_casehundredth_test_caser"  all_source_typesdays_since_registrationactivity_datesrG  sorted_datesrz  ry  r   r  current_countr  achievement_categoriesrarity_countsachievementr  r  total_possible_achievementsr  r  r(   s                                  r)   $get_user_achievements_and_milestonesz1MongoHandler.get_user_achievements_and_milestones  sT	   I	Tdo22G$1JJ  d<##% %J (115'2BE E  D
  G#(5EFFF LJ :!##",Q-##+*#C' +#2<#@#J#J#L#L&% %    :"$$",Q-##*.#<' +#2<#@#J#J#L#L&% %    :"$$%/^"##,/#<' +#5l#C#M#M#O#O$% %    :#%%&0n###./#=' +#6|#D#N#N#P#P$% %    __:_____L<  A%%##,/#U3|+<+<#U#U#U( -OY#c:b>,#?#I#I#K#K#K_c(% %     IHH&&'788 	##',#D# -OY#c:b>,#?#I#I#K#K#K_c)% %    xx%% !+3?+<+<tL?Q+Q*W'*b00 '',!/'M 0$-(,\(:YB=O=O=O(O'Z'Z'\'\"*) )    +b00 ''.!1'M 0$-(,\(:YB=O=O=O(O'Z'Z'\'\",) )    +c11 ''+!.'N 0$-(,\(:YC=P=P=P(P'['[']']"() )     )!$$ @ @B"&&r,'7'<'<'>'>????%n55
!"s<0011 + +AAvv)*&q/L1,==CqHH&!+%(^%D%D
)* ^<<
?? ''-!1'K &$1'1"~l'C'M'M'O'O",) )    ## ''.!1'L &$1'1"~l'C'M'M'O'O"() )    !O  
OOMr!!&&(, .#;!.!3s :( (     ##&&(, /#;!.!3s :( (     $$&&(,!/#<!.!4 ;( (    <  1$$&&*"<00,#;!$\!2!2Q!6# =( (    "%\!2!2%'"M+ + +&z2#99978*84&x000A5000 %X...,-M&)f%%%*%%%% +-'%7:U%UY\$\! '9)./Da)H)H ,#2#9!.&A  "889NOO>M(W(:(:SW=I*S,q//t ! !"  $:KLLL 	T 	T 	TLLESVVEEFFF$1RSSSSSSSS	Ts%   A)Y- ,X Y- -
Z07.Z+%Z0+Z0c                 V    |dk    rdS |dk    rdS |dk    rdS |dk    rdS |d	k    rd
S dS )z4Get achievement level based on completion percentager  	Legendaryr8  Masterr   Expert   Intermediater   BeginnerNovicer   )r'   r  s     r)   r  z#MongoHandler._get_achievement_level  sW     B&&;"b((8"b((8"b((!>"b((:8r   c                 N  ) 	 |                      |          sdddS ddlm}m}  |j                    }|dk    r| |d          z
  }ng|d	k    r| |d
          z
  }nQ|dk    r| |d          z
  }n;|dk    r| |d          z
  }n%|dk    r| |d          z
  }n| |d          z
  }t	          | j                            ddd|iiiddddiddidddddgiddgiiddidd id!d id"id#d$d%iig                    }g }t          |          }	|D ]D}
| j        	                    d&|
d&         iddddd'          }|r|
d$         }|

                    d(d          }|

                    d)d          d*z  }t          |
d+                   }d}|
                    d          r||d         z
  j        }d}|dk    r|dk    rt          ||z  d*z  d*          }|                    t          |
d&                   |d,         |d-         |
                    d.d/          |t          |d0          t          |d0          ||t          |d0          d1d2           F|rvd3 |D             }d4 |D             }d5 |D             }d6 |D             }t          t!          |          t          |          z  d0          t#          |          t          |          d0z           t#          |          t%          t          |          d7z                     t#          |          t%          t          |          d8z                     d9|r-t          t!          |          t          |          z  d0          nd|r%t#          |          t          |          d0z           nd|rt          |          ndd:t          t!          |          t          |          z  d0          t#          |          t          |          d0z           t#          |          t%          t          |          d7z                     d;t          t!          |          t          |          z  d0          t#          |          t          |          d0z           t#          |          t%          t          |          d7z                     d;d<}|D ]ފ)t          )fd=|D                       dz   }|t          |	|z
  dz   |	z  d*z  d          d>)d?<   t          )fd@|D                       dz   }|)d?         dA<   t          |	|z
  dz   |	z  d*z  d          )d?         dB<   )d?         dC         dDz  )d?         dB         dEz  z   )dF         d)         dEz  z   }t          |d          )d?         dG<   |                    dH dIJ           t)          |          D ]\  })|dz   )d?         dK<   ni }g }|r|dLdM         }|                    dNdO                    dP |D                                   t          |          dk    rT|d         d?         dG         }|d%         d?         dG         }||z
  }|                    dQt          |d           dR           |rM|dS         dT         } |                    dU|             |dS         dV         }!|                    dW|! dX           g }"|rdY |D             }#|#r&|"                    dZt          |#           d[           d\ |D             }$|$r&|"                    d]t          |$           d^           |rR|d)         dT         }%|%d_k     r|"                    d`           |dA         dT         }&|&dak     r|"                    db           ||                                |                                |	||||"|r|d         ndL|r*|
                    dSi           
                    dTd          ndt          dc |D                       t          dd |D                       t          de |D                       t          df |D                       dgdhdi	}'dI|'djS # t.          $ r9}(t0                              dkt          |(                      ddldcY dL}(~(S dL}(~(ww xY w)mz6Get user comparison and benchmarking data (admin only)Fra   r/   r   r
   r   rb   r.  r  r?  r  rG  r}  r  r  r  r  r7   r   rH  rI  rJ  r  r  r  r  r  r  r  rY  r7  rL  rK  )r3   r  r  r  r"  r  rN  rX  r  r   r3   rY  r  r  r  r"  r5   r-   r6   r+   rx  )rM  r  r  source_type_diversityr  efficiency_score)r^   r5   r-   r6   metricsc                 *    g | ]}|d          d         S r  rM  r   rQ  s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>(  s"    #]#]#]AiL1B$C#]#]#]r   c                 N    g | ]"}|d          d         dk    |d          d         #S )r  r  r   r   rQ  s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>)  sc      $M  $M  $MAdefodp  rG  eH  KL  eL  eLAiL1F$G  eL  eL  eLr   c                 *    g | ]}|d          d         S )r  r  r   rQ  s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>*  s!     W W W!9n!= W W Wr   c                 *    g | ]}|d          d         S r  r  r   rQ  s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>+  s"    $_$_$_!Qy\2D%E$_$_$_r   g      ?g?)rj  mediantop_25_percentiletop_10_percentile)rj  r  fastest)rj  r  r  )r   completion_timer  
efficiencyc                 P    g | ]"}|d          d         d          d         k     |#S r  r   r   rR  r+   s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>H  s_      -Q  -Q  -Q11Y<XiKjmqr{m|  ~O  nP  LP  LPQ  LP  LP  LPr   )rM  test_case_percentilerankingsc                 P    g | ]"}|d          d         d          d         k     |#S r  r   r  s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>O  s_      .T  .T  .TAAiLYkLlost}o~  @R  pS  MS  MSa  MS  MS  MSr   r  efficiency_percentiler  rv  rw  r  overall_scorec                     | d         d         S )Nr  r  r   r  s    r)   r  zCMongoHandler.get_user_comparison_and_benchmarking.<locals>.<lambda>\  s    1Z=3Q r   Tr  positionNrz  zTop 3 performers: z, c                     g | ]
}|d          S )r5   r   rQ  s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>j  s    ?b?b?ba&	?b?b?br   z.Performance gap between top and bottom users: z pointsr   rj  r"  r  zTop 25% threshold: z test casesc                 6    g | ]}|d          d         dk     |S )r  r  r   r   rQ  s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>  s,    !d!d!d*o@^ac@c@c!@c@c@cr   zProvide additional support for z low-performing usersc                 6    g | ]}|d          d         dk    |S r  r  r
  r   rQ  s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>  s,    "f"f"f:A_ceAeAe1AeAeAer   zRecognize and reward z high-performing usersr
  z4Implement training programs to improve success ratesr   z.Provide efficiency training and best practicesc                 6    g | ]}|d          d         dk    |S r  r   rQ  s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>  s-    )m)m)m*VeHfjlHlHl!HlHlHlr   c                 J    g | ] }d |d         d         cxk    rdk     n n|!S )rM  r  r  r
  r   rQ  s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>  sD    $m$m$m12:WfIgClClClCljlClClClClClQClClClr   c                 J    g | ] }d |d         d         cxk    rdk     n n|!S )r+  r  r  rM  r   rQ  s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>  sD    'p'p'pabAjMZiLjFoFoFoFomoFoFoFoFoFoFoFoFor   c                 6    g | ]}|d          d         dk     |S )r  r  r+  r   rQ  s     r)   rV  zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>  s-    -p-p-pAAjMZiLjmoLoLoaLoLoLor   )rh  ri  rj  rk  )top_performeraverage_performanceperformance_distribution)	r  r  r  ro  user_benchmarks
benchmarksr#  r	  r1  )r0   comparison_dataz0Error getting user comparison and benchmarking: z"Failed to retrieve comparison data)r_   r   r   rF   rf   r   r_  r   r   r>   rV   r/  r  r   r%   rD  rs  r  r  r   r  joinrh   r&   r   r$   )*r'   ri   r  r   r   r=  r  user_performance_datar  r   	user_perfry  rM  r  r  r  r  r  test_case_countscompletion_timessuccess_ratesefficiency_scoresr  test_case_rankingefficiency_rankingr  r   r#  r  	top_scorebottom_scoreperformance_gapr  top_25_thresholdr	  r'  high_performersr  avg_efficiencyr  r(   r+   s*                                            @r)   $get_user_comparison_and_benchmarkingz1MongoHandler.get_user_comparison_and_benchmarking  s   [	W==// b#(5`aaa 54444444!(/##Ce## 99!#4#4#44

&& 99!#4#4#44

'' 99"#5#5#55

	)) 99"#5#5#55

&& 99##6#6#66

 99"#5#5#55
 %))B)BL6:*>?@%)/,24F+GEI{3K+LaQR*S T% &1.$A'-}&=&,m%<
 
 
 -r23D * * % %!" !O344K2 ' '	#4==uiPUFV>W"#	Z Z       &/0B&CO*3--8Mq*Q*Q'#,==#C#Cc#IL,/	.0I,J,J) %&M#''55 P),|L/I)I(O ()$&**/BQ/F/F+.BU0UY\/\^a+b+b(#**#&y'7#8#8 ,V 4!-g!6 , 0 0 @ @/>389La3P3P,1,,B,B5J-:056F0J0J$ $, ,      < #]#]_#]#]#]  $M  $MQ`  $M  $M  $M  W W W W W$_$_$_$_$_! $)-=)>)>EUAVAV)VXY#Z#Z"()9":":3?O;P;PTU;U"V-34D-E-Ec#N^J_J_bfJfFgFg-h-34D-E-Ec#N^J_J_beJeFfFf-g	# # _o#u5-=)>)>EUAVAV)VXY#Z#Z#ZtuZj"q&)9":":3?O;P;PTU;U"V"Vpq<L#S3'7#8#8#8RS( ( $)]););c->P>P)PRS#T#T"("7"7M8J8Ja8O"P-3M-B-B3s=GYGY\`G`CaCa-b% % $)->)?)?#FWBXBX)XZ[#\#\"():";";C@Q<R<RVW<W"X-34E-F-Fs3O`KaKadhKhGiGi-j# ## 
2 , P PD(+  -Q  -Q  -Q  -Q  -Q  -Q  -Q  )R  )R  UV  )V%+<05{EV7VYZ7Z^i6ilo6oqr0s0s( (D$ *-  .T  .T  .T  .T  .T  .T  .T  *U  *U  XY  *Y&5GD$\2@E{UgGgjkGkozFz  ~A  GA  CD  AE  AED$%<= Z()?@3FZ()@ACGHY7#=> "
 9>mQ8O8OD$_55  $$)Q)Q[_$```  )99 9 9GAt34q5D$Z009  
 H Y!0!!4 eTYY?b?bSa?b?b?b5c5c e efff ''!++ / 2: > OI#22#6z#B?#SL&/,&>OOO$wUZ[jlmUnUn$w$w$wxxx  Y%/%=i%HNOO$TN$T$TUUU'1,'?@S'T$OO$W:J$W$W$WXXX !O a!d!d_!d!d!d! y#**+wSQ_M`M`+w+w+wxxx #g"fo"f"f"f" q#**+o3CWCW+o+o+oppp  a'1.'A)'L$'",,'../efff%/%=i%HN%**'../_```  +(2244MMOO(3#2($#2;J%T_Q%7%7PTak+r:>>,+K+K+O+OPY[\+]+]+]qr%()m)m_)m)m)m%n%n #$m$m$m$m$m n n#&'p'p?'p'p'p#q#q),-p-p-p-p-p)q)q	1 1	 	 O*  $HHH 	W 	W 	WLLTCPQFFTTUUU$1UVVVVVVVV	Ws#   a! aa! !
b$+.bb$b$c           
      F   	 t          | j                            d|iddddd                              dd                    }|sdddidS t	          d	 |D                       }t          |          }g }|dk    r|                    d
           |dk    r|                    d           |dk    r|                    d           |dk    r|                    d           |dk    r|                    d           t          d |D                       t          d |D                       t          d |D                       t          d |D                       t          d |D                       d}d |                                D             }d |                                D             }|r|d         nd|||||rd |D             ndgd}	d|	dS # t          $ r9}
t          
                    d t          |
                      d!d"d#cY d$}
~
S d$}
~
ww xY w)%z*Get user learning and development insightsr^   rb   r~  r7   Tr1   z No test cases found for analysis)r0   learning_insightsc              3   P   K   | ]!}|                     d           |d          V  "dS r  r  rF  s     r)   r6  z:MongoHandler.get_user_learning_insights.<locals>.<genexpr>  s9      #d#d"bffUbNcNc#dB}$5#d#d#d#d#d#dr   z$Beginner - First test case generatedrJ  z%Novice - Basic understanding achievedr  zIntermediate - Consistent usagerG  zAdvanced - Proficient userr   zExpert - Master levelc                 D    g | ]}|                     d           dk    |S )r   r  r  rF  s     r)   rV  z;MongoHandler.get_user_learning_insights.<locals>.<listcomp>  s/    #^#^#^2rvvm?T?TX]?]?]B?]?]?]r   c                 D    g | ]}|                     d           dk    |S )r   r  r  rF  s     r)   rV  z;MongoHandler.get_user_learning_insights.<locals>.<listcomp>  s/    %b%b%bRAVAVZaAaAabAaAaAar   c                 D    g | ]}|                     d           dk    |S )r   r  r  rF  s     r)   rV  z;MongoHandler.get_user_learning_insights.<locals>.<listcomp>  s/    (d(d(dBFF=DYDY]cDcDcDcDcDcr   c                 D    g | ]}|                     d           dk    |S )r   r  r  rF  s     r)   rV  z;MongoHandler.get_user_learning_insights.<locals>.<listcomp>  s/    )f)f)fRVVMEZEZ^eEeEe"EeEeEer   c                 D    g | ]}|                     d           dk    |S )r   r  r  rF  s     r)   rV  z;MongoHandler.get_user_learning_insights.<locals>.<listcomp>  s/    %a%a%aRAVAVZ`A`A`bA`A`A`r   )url_testingimage_testingjira_integrationazure_integrationtext_analysisc                 $    g | ]\  }}|d k    |S )rJ  r   r   arear   s      r)   rV  z;MongoHandler.get_user_learning_insights.<locals>.<listcomp>  s"    SSS+$QR




r   c                 $    g | ]\  }}|d k     |S )rz  r   r  s      r)   rV  z;MongoHandler.get_user_learning_insights.<locals>.<listcomp>  s(     Z Z Z+$PUXYPYPYPYPYPYr   r   zNew Userc                 f    g | ].}d |                     dd                                           d/S )z	Focus on rS  rT  z to improve skills)r   r   )r   r  s     r)   rV  z;MongoHandler.get_user_learning_insights.<locals>.<listcomp>  sK     $ $ $W[RS# 6 6 < < > >RRR$ $ $r   z)Continue exploring different source types)current_stagelearning_progressionskill_development	strengthsimprovement_areasr	  z!Error getting learning insights: Fz$Failed to retrieve learning insightsr/   N)rf   r   rg   r   r  r   r   r   r&   r   r$   r%   )r'   r^   r   r  r  learning_stagesskill_areasr  r  r  r(   s              r)   get_user_learning_insightsz'MongoHandler.get_user_learning_insights  s   7	Ydo22G$1JJ  d<##% %J
  o#'yJl>mnnn !$#d#d
#d#d#d d d": !O1$$&&'MNNN1$$&&'NOOO2%%&&'HIII2%%&&'CDDD2%%&&'>???  ##^#^#^#^#^__!$%b%b:%b%b%b!c!c$'(d(dj(d(d(d$e$e%()f)fz)f)f)f%g%g!$%a%a:%a%a%a!b!b K TS1B1B1D1DSSSI Z Z9J9J9L9L Z Z Z 9H!W!4!4Z(7%0&%6 '$Z $ $_p$ $ $ $-X,Y	! 	!  $:KLLL 	Y 	Y 	YLLESVVEEFFF$1WXXXXXXXX	Ys%   AG FG 
H '.HH H c                 V   	 |t          j                    t          d          z   t          j                    d}t          j        dd          }t          j        ||d          }|S # t          $ r5}t          	                    dt          |                      Y d	}~d	S d	}~ww xY w)
zGenerate JWT token for userrG  r.  )r^   expiatJWT_SECRET_KEY$your-secret-key-change-in-productionHS256)	algorithmzError generating JWT token: N)r   rF   r   osgetenvjwtrC   r&   r   r$   r%   )r'   r^   payload
secret_keyrU   r(   s         r)   rY   zMongoHandler.generate_jwt_token  s    	"((9"+=+=+==(( G #35[\\JJw
gFFFEL 	 	 	LL@A@@AAA44444	s   A&A) )
B(3*B##B(c                 >   	 t          j        dd          }t          j        ||dg          }|                    d          }|rd| j                            d|i          }|rF|                    dd          r0d|d         |d	         |d
         |                    dd          ddS dddS # t          j        $ r dddcY S t          j        $ r dddcY S t          $ r9}t                              dt          |                      dddcY d}~S d}~ww xY w)z%Verify JWT token and return user infor  r  r  )
algorithmsr^   r3   r9   Tr-   r5   r6   r+   r;   r   FzInvalid or expired tokenr/   zToken expiredzInvalid tokenzError verifying JWT token: zToken verification failedN)r  r   r!  decoderV   r   r>   ExpiredSignatureErrorInvalidTokenErrorr&   r   r$   r%   )r'   rU   r#  r"  r^   r+   r(   s          r)   verify_jwt_tokenzMongoHandler.verify_jwt_token  s   	N#35[\\Jj
yIIIGkk),,G ,55ug6FGG 	DHH[$77 	#'"&u+%)']$(L$(HHVV$<$<	! !    %1KLLL( 	B 	B 	B$AAAAA$ 	B 	B 	B$AAAAA 	N 	N 	NLL?s1vv??@@@$1LMMMMMMMM	Ns0   B'B/ *B/ /DD	D#.DDDc                 <   	 t          | j                            d|idddddd                              dd                              |                    }|S # t
          $ r6}t                              dt          |                      g cY d}~S d}~ww xY w)z&Get all test cases for a specific userr^   rb   )r3   	test_datar7   r   item_idr7   r   zError getting user test cases: N)	rf   r   rg   r   r   r&   r   r$   r%   )r'   r^   r   r   r(   s        r)   get_user_test_casesz MongoHandler.get_user_test_cases  s    		do22G$1YZ[[  d<$$UU5\\3 3J
  	 	 	LLC3q66CCDDDIIIIII	s   AA 
B%+BBBc           	         	 t          t          j                              }||t          j                    |||i |d}| j                            |           t                              d| d| d|            |S # t          $ r>}t          
                    dt          |                      t          d          d}~ww xY w)zJSave test case data and generate unique URL with optional user association)r3   r+  r7   url_keyr,  r   rd   r^   z&Successfully saved test case with ID: z, source_type: z, user_id: zError saving test case: z$Failed to save test case to databaseNr%   rD   rE   r   rF   r   rG   r   r   r&   r$   )r'   r+  r,  r   r^   	unique_iddocumentr(   s           r)   save_test_casezMongoHandler.save_test_case$  s    	DDJLL))I &&o//$"*"	 	H O&&x000KK|||[f||sz||}}} 	D 	D 	DLL<CFF<<===BCCC	Ds   A:A= =
C9C  Cc                 \   	 | j                             d|idd|ii          }|j        dk    rt                              d|            dS t                              d|            dS # t          $ r5}t                              d	t          |                      Y d
}~dS d
}~ww xY w)z5Update the status dictionary for a test case documentr/  rT   rd   r   z%Successfully updated status dict for Tz'No document found to update status for FzError updating status dict: N)	r   rX   rq   r   r   r7  r&   r$   r%   )r'   r/  status_valuesrQ   r(   s        r)   update_status_dictzMongoHandler.update_status_dict9  s    	_//G$(M23 F $q((MGMMNNNtRRRSSSu 	 	 	LL@A@@AAA55555	s   A	A, A, ,
B+6*B&&B+c           
      b   	 |                     d          |                     d          |                     d          |                     d          |                     d          t          j                    |                     d          |                     d          d}| j                            |           t
                              d	|                     d                      d
S # t          $ r5}t
                              dt          |                      Y d}~dS d}~ww xY w)z"Track user session and page visitsr  r  r  referrerpage_visitedcountrycity)r  r  r  r8  r9  r;  r:  r;  zTracked user session: TzError tracking user session: NF)
rV   r   rF   r   rG   r   r   r&   r$   r%   )r'   session_datasession_docr(   s       r)   track_user_sessionzMongoHandler.track_user_sessionJ  s)   	*..|<<*..|<<*..|<<(,,Z88 , 0 0 @ @%_..'++I66$((00	 	K )44[AAAKKQ1A1A,1O1OQQRRR4 	 	 	LLAQAABBB55555	s   C+C/ /
D.9*D))D.c                 D   	 |                     d          |                     di           |                     d          |                     d          |                     d          t          j                    |                     d          |                     dg           |                     dd	          d
	}|                     d          r|                     d          |d<   |                     d          r|                     d          |d<   | j                            |           t
                              d|                     d                      dS # t          $ r5}t
                              dt          |                      Y d}~dS d}~ww xY w)z"Track user events and interactionsrP  
event_datar  r  r  r   test_case_types
item_countr   )	rP  r@  r  r  r  r;  r   rA  rB  r^   	user_rolezTracked event: TzError tracking event: NF)
rV   r   rF   r   rG   r   r   r&   r$   r%   )r'   r@  	event_docr(   s       r)   track_eventzMongoHandler.track_event^  s   	(nn\::(nn\2>>(nn\::(nn\::(nn\::%_..)~~m<<#->>2CR#H#H(nn\1==
 
I ~~i(( A'1~~i'@'@	)$~~k** E)3)D)D	+&%00;;;KKH*..*F*FHHIII4 	 	 	LL:#a&&::;;;55555	s   EE   
F**FFrG  c                 ^   	 |rE|rCt          j        |d          }t          j        |d          t          d          z   }d||di}n*t          j                    t          |          z
  }	dd|	ii}i |}
|r||
d<   |r
||
d<   ||d<   | j                            |          }| j                            |
          }i |
d	d
i}| j                            |          }i |
d	di}| j                            |          }di |
d	diidddddddgidddgigidddiiiddddddiiddddididddiig}t          | j                            |                    }di |
ddg d d!id"d#idd#ddididddiig}t          | j                            |                    }d|
idd$d%id&d%id'd%id(ddid)idd*diig}t          | j                            |                    }di |
dd+did,iddd-d.id/d.id0d.iddid1ig}t          | j                            |                    }di |
dd+did,idddddddgidddgigidddiiiddddddiiddd-d.iddid2idd3diig}t          | j                            |                    }di |
dd+didd4d d5idd6dd7d8d9gid:dd7d8d;gid<dd7d8d=gid>d?dididiid-d.id-d@iddidAiddBdiig}t          | j                            |                    }|r5d4|||t          |d4k    r||z  dCz  nd4dC          ||||r|d4         nd|||dDS ||||t          |d4k    r||z  dCz  nd4dC          ||||r|d4         nd|||dDS # t          $ r5}t                              dEt          |                      Y d}~dS d}~ww xY w)FzZGet analytics summary for the specified date range or number of days with optional filtersr  rb   r.  r;  r  r   r   r^   rP  generate_button_clickrS  r  z
$addFieldseffective_source_typer  z$andrN  rY  Nr  z$event_data.source_type)ifthenelseT)rM  rN  rN  rH  z$effective_source_typerJ  rZ  rX  r   r   rL  )rP  rA  rS  z$test_case_typesz$yearz
$timestampz$monthz$dayOfMonth)r  r  r   )r3   eventsr3   rM  )rP  &event_data.generation_duration_secondsr  z'$event_data.generation_duration_secondsr7  rK  )r3   avg_generation_timemin_generation_timemax_generation_timetotal_generations)r3   rN  r   rN  r   )rP  rM  rB  
item_range$ltez$item_countrJ  z	1-5 itemsr   z
6-10 itemsr   z11-20 itemsz	20+ itemsz!$event_data.average_time_per_item)r3   rN  avg_time_per_itemr   z_id.item_ranger  )total_sessionsr_  generate_clickssuccessful_generationsr  r@  test_case_type_distributionr  generation_timingtiming_by_sourcetiming_by_itemsperiod_daysz!Error getting analytics summary: )r   strptimer   rF   r   r   r   rf   r_  r  r&   r   r$   r%   )r'   r  r  r/  r   r^   start_datetimeend_datetimedate_filtercutoff_datebase_filterrU  r_  generate_filterrV  success_filterrW  source_type_pipelinesource_type_statstest_case_type_pipelinetest_case_type_statsdaily_activity_pipeliner  timing_pipelinetiming_statstiming_by_source_pipelinerZ  timing_by_items_pipeliner[  r(   s                                 r)   get_analytics_summaryz"MongoHandler.get_analytics_summaryz  s   H	 Ch C!)!2:z!J!J'0:FFXYIZIZIZZ*^L,Y,YZ 'o//)2F2F2FF*V[,AB *[/K 9-8M*  1)0I&)0I& ":JJ;WWN  4DD[QQL UTl<STTO"7GGXXO RQ\;PQQN%)%>%N%N~%^%^" OkO<9NOOP+#)!&(> ?!&(< =, # %3$=" "	.   3d[]5^5^_`#;vqkRRS7B-(!$ $ !%T%>%H%HI]%^%^ _ _   Ak  A9Nos|~cc  A  A  A  B./#5LLM7B-(	'# $((A(K(KLc(d(d#e#e  ;'!(, 7"*L!9 -|< 
  &qk   5!*%'# "$";"E"EF]"^"^__N  !"7?H$>O   
 ,24]+^,24]+^,24]+^*0!  O   9 C CO T TUUL  !"7?H$>O   
 +#)!&(> ?!&(< =, # %3$=" "	.   3d[]5^5^_`3,24]+^$a[  
 0"561)%4  $D$=$G$GHa$b$bcc  !"7?H$>O.21"="=	    $#'-q/A&B(3$+/5r7J.K0<,37=r?R6S8E8C6. 6.1*
.& 
.&)"& &'* -34]+^*02U)V$a[1  4 +Q/0C"($F #4#<#F#FG_#`#`aaO   '($0'6.D$'\kno\o\o)?/)QTW)W)Wuvx{$|$|0A3G&4<H)Rad(8'6#'  " '5$0'6.D$'\kno\o\o)?/)QTW)W)Wuvx{$|$|0A3G&4<H)Rad(8'6#'    	 	 	LLESVVEEFFF44444	s   L5M- 84M- -
N,7*N''N,c                 j   	 i }|r|                     d          rd|d         i|d<   |                     d          r#d|v r|d         |d         d<   nd|d         i|d<   |                     d          r|d         |d<   |                     d          r|d         |d<   t          | j                            |dd	i                              dd
                              d                    }|S # t          $ r5}t                              dt          |                      Y d}~dS d}~ww xY w)z,Get detailed analytics with optional filtersr  r   r;  r  rS  rP  r   r3   r   r   i  z"Error getting detailed analytics: N)
rV   rf   r   rg   r   r   r&   r   r$   r%   )r'   filtersmatch_criteriarL  r(   s        r)   get_detailed_analyticsz#MongoHandler.get_detailed_analyticsF  sp   	N K;;|,, R397<;P2QN;/;;z** T"n44>Ej>Q{3F;;7=wz?R6S{3;;|,, I3:<3HN<0;;}-- K4;M4JN=1 $388
  d;##EE$KK1 1F
 M 	 	 	LLFc!ffFFGGG44444	s   C0C3 3
D2=*D--D2c           	         	 | j                             d|i          }|st                              d|            dS t                              d| d|            t                              dt          |                                                      d|v rt                              dt          |d                               t          |d         t                    rCt                              d	t          |d                                                               nKt          |d         t
                    r0t                              d
t          |d                               d}|rfd|vrbd|vr^t          j                    }| j                             d|idd| |d| |ii           d}t                              d| d|            d}d|v r:t          |d         t
                    rd}t                              d|            d}d|v ret          |d         t                    rJd|d         v r@t          |d         d         t
                    rd}t                              d|            |rt                              d| d|            t          j                    }| j                             d|idd| |d| |ii          }	|	j        dk    rt                              d|            dS t                              d|            dS |r|d         }
d}t!          |
          D ]\  }}|                    dd          }||k    rt                              d|            | j                             d|idd| d|ii          }	|s<t          j                    }| j                             d|idd| |d| |ii           d} n|s"t                              d| d |            dS dS d|v rQd!|d         v rF|d         d!         }
d }d"|v ra|                    d"          }t          |          d#k    r9|d          d"|d$          d"|d%          }t                              d&|            t!          |
          D ]\  }}|                    d|                    d'd                    }|                    d(|                    d)d                    }|s|r|                    d*          }|D ]e}|                                                    d+          r<|                                                    d+d                                          } nf|ss|                    d*          }|D ][}|                                }|rC|                    d,          s*|                    d-          s|                    d.          r|} n\|r||v rt                              d/|            | j                             d|idd0| d1|ii          }	|s$| j                             d|idd| |ii           |	j        dk    r t                              d2|             dS |rd3|v r|                    d3          d                                         }||k    rt                              d4|            | j                             d|idd0| d1|ii          }	|s$| j                             d|idd| |ii           |	j        dk    r t                              d5|             dS |r||v rt                              d6|            | j                             d|idd0| d1|ii          }	|s$| j                             d|idd| |ii           |	j        dk    r t                              d7|             dS |r|r|                    |d"z             s|                    |d8z             s||k    rt                              d9| d:|            | j                             d|idd0| d1|ii          }	|s$| j                             d|idd| |ii           |	j        dk    r t                              d;|             dS |r||v rt                              d<           | j                             d|idd0| d1|ii          }	|r&|s$| j                             d|idd| |ii           |	j        dk    r t                              d7|             dS t!          |
          D ]\  }}|                    d=          |k    s|                    d>          |k    rt                              d?|            |                    d|                    d'd                    }| j                             d|idd0| d1|ii          }	|r&|s$| j                             d|idd| |ii           |	j        dk    c S t                              d@| d|            dS t                              dA| dB           dS # t,          $ r5}t                              dCt/          |                      Y d }~dS d }~ww xY w)DNr/  z No document found with url_key: Fz/Updating status for test case with identifier 'z' in document zDocument structure: r+  ztest_data type: ztest_data keys: ztest_data list length: .r   rT   zstatus.zstatus_timestamps.Tz-Updated central status dictionary for title: z with timestamp: z Shared view update detected for z"URL structure update detected for z#Updating status for URL structure: z = r   z/Successfully updated status for URL structure: z+Failed to update status for URL structure: Titler  z"Found shared view match by title: z
test_data.z.StatuszNo test case found with title 'z' in shared view document r   rS  rz  rb   rx  zExtracted UI identifier: r   Contentcontent
zTitle:TC_TC_FUNC_TC_UI_zFound match in title: ztest_data.test_cases.z.statusz/Successfully updated status by title match for (zFound match by base title: z4Successfully updated status by base title match for z)Found match in content for test case ID: z1Successfully updated status by content match for rT  zFound match for UI identifier z in title: z7Successfully updated status by UI identifier match for zFound match in contentrV  zTest Case IDzFound direct ID match at index zNo test case found matching 'z	Document z has no test casesz!Error updating test case status: )r   r>   r   r$   r   rf   r   r  r   r  r   r   rF   rX   rq   r7  r  rV   splitstriprE  r   r&   r%   )r'   r/  rV  rd   doctitle_foundcurrent_timeis_shared_viewis_url_structurerQ   r   foundidxrG  r   ui_identifierpartsrw  linesline
base_titler(   s                         r)   update_test_case_statusz$MongoHandler.update_test_case_statusb  s   \	/**Iw+?@@C IIIJJJu KKo,oofmooppp KKAtCHHJJ/?/?AABBBc!!GtC4D/E/EGGHHHc+.55 SKK R4K8H8M8M8O8O3P3P R RSSSSK 0$77 SKK Q#c+>N:O:O Q QRRR  K  {< 7 7C|<S<S  (00**(4l44f???!   #yLyykwyyzzz #Nc!!j[1A4&H&H!!%HwHHIII  %c!!j[1A4&H&H![\_`k\lMlMlq{|  AL  }M  NY  }Z  \`  ra  raMl#' JJJKKK d [,[[SY[[\\\  (0033(4l44f???!  (1,,KK `R^ ` `aaa4NN#_Q]#_#_``` 5 K -
 (44  GCFF7B//E ,,$P$P$PQQQ!%!;!;&0#&?3&?&?&?%HI" "  + 
+3?+<+<L O66!*G 4$*(9%(9(96(DU(D(Dl-&!"   !%+ -.  !NN#v\#v#vmt#v#vwww 5t##K8H(H(H -l;
 !%,&&(..s33E5zzQ+08(K(KeAh(K(Kq(K(K$O$O$OPPP  )44 }( }(GCFF7BFF7B,?,?@@E ffYy"0E0EFFG ! *W * 'd 3 3$) & &D#zz||66x@@ &(,

(<(<Xr(J(J(P(P(R(R %&
  % *$+MM$$7$7E(- * *'+zz||#' !*T__U-C-C !*tWaGbGb !*fjfufuv~ff !*,0E$)E  (!6!6$DU$D$DEEE!%!;!;&0#&Jc&J&J&JF%ST" "  +  O66!*G 4!'*;E*;*;V)D E  
 "0144"KK(hZf(h(hiii#'44
  ,!4!4%1%7%7%<%<Q%?%E%E%G%G
 J.."KK(Rj(R(RSSS%)_%?%?!*G 4!'*N#*N*N*NPV)W X& &F $/ " $ : :%.$8%+.F.F.F-O$P!" !" !"
  &4q88 &,qco,q,q r r r'+tt  (<7#:#:$^P\$^$^___!%!;!;&0#&Jc&J&J&JF%ST" "  +  O66!*G 4!'*BL*B*BF)K L  
 "0144"KK(j\h(j(jkkk#'44 % , , ",,]S-@AA ,!,,]S-@AA,!]22"KK(j(j(jch(j(jkkk%)_%?%?!*G 4!'*N#*N*N*NPV)W X& &F $/ " $ : :%.$8%+.F.F.F-O$P!" !" !"
  &4q88 &,ufs,u,u v v v'+tt  (<7#:#:$=>>>!%!;!;&0#&Jc&J&J&JF%ST" " !   O66!*G 4!'*;E*;*;V)D E  
 "0144"KK(j\h(j(jkkk#'44  )44 9 9GCvvn--==AWAW[gAgAg$Kc$K$KLLL "ww0C0C D D!%!;!;&0#&Jc&J&J&JF%ST" " !   O66!*G 4!'*;E*;*;V)D E  
  &4q8888! Bh& d|dd[bddeeeuF7FFFGGGu 	 	 	LLESVVEEFFF55555	s`   ;j Kj j 4C#j I;j C
j $Bj =Cj Bj %C(j !j 1j 
k*kkc                    	 | j                             d|i          }|sY| j                             d|i          }|rt                              d|            nt                              d|            |S # t
          $ r>}t                              dt          |                      t          d          d}~ww xY w)z"Retrieve test case data by URL keyr/  r3   Found document by _id: 'No test case found for URL key or _id: zError retrieving test case: z*Failed to retrieve test case from databaseN)r   r>   r   r   r7  r&   r$   r%   )r'   r/  rQ   r(   s       r)   get_test_casezMongoHandler.get_test_case  s    	J_--y'.BCCF X115'2BCC XKK C' C CDDDDNN#VW#V#VWWWM 	J 	J 	JLL@A@@AAAHIII	J   A8A; ;
C9B>>CFc                    	 | j                             d|i          }|s[| j                             d|i          }|rt                              d|            nt                              d|            dS d|v r$t                              d|d                     nt                              d           d	|v rt          |d	         t                    rt          |d	                   D ]\  }}t          |t                    rS|	                    d
d          }|	                    dd          }|r$t                              d| d| d| d           mt                              d| dt          |                      nd	|v rt          |d	         t                    r d|d	         v rt          |d	         d                   D ]\  }}t          |t                    r{|	                    d
|	                    dd                    }|	                    d|	                    dd                    }|r$t                              d| d| d| d           t          |t                    r	 ddlm}  ||          }	|	rt          |	          D ]\  }
}|	                    d
|	                    dd                    }|	                    d|	                    dd                    }|r't                              d| d|
 d| d| d	           nt                              d| d           r# t          $ r+}t                              d| d|            Y d}~d}~ww xY wt                              d| dt          |                      ncd	|v r_t          |d	         t                    rDt                              dt!          |d	                    d|d	         dd          d           i S d|v rA|d         r9t                              dt!          |d                    d            |d         S i }d	|v rt          |d	         t                    rst                              d!           |d	         D ]N}t          |t                    r7d
|v r3|	                    d
d          }|	                    dd          }|r|||<   Ond	|v rt          |d	         t                    rd|d	         v rut                              d"           |d	         d         D ]I}t          |t                    r\|	                    d
|	                    dd                    }|	                    d|	                    dd                    }|r|||<   tt          |t                    rddlm} 	  ||          }|ru|D ]r}t          |t                    r[|	                    d
|	                    dd                    }|	                    d|	                    dd                    }|r|||<   s# t          $ r(}t                              d#|            Y d}~Ad}~ww xY wKn+d	|v rt          |d	         t                    rd	|d	         v rt                              d$           t          |d	         d	         t                    r|d	         d	         D ]}t          |t                    r||	                    d
|	                    dd                    }|	                    d|	                    dd                    }|r&|||<   t                              d%| d&| d'           n"d	|v r7t          |d	         t                    rt                              d(           i S d	|v rRt          |d	         t                    r6d|d	         v r+t          |d	         d         t                    rt                              d)           ddlm} 	  ||d	         d                   }|r|D ]}t          |t                    r||	                    d
|	                    dd                    }|	                    d|	                    dd                    }|r&|||<   t                              d%| d&| d*           n# t          $ r(}t                              d+|            Y d}~nd}~ww xY wnd	|v rt          |d	         t                    rod|d	         v rdt          |d	         d         t                    rBt                              d,           ddlm} 	 |d	         d         D ]}t          |t                    rd-|v r|d-         }|rt          |t                    r ||          }|r|D ]}t          |t                    r||	                    d
|	                    dd                    }|	                    d|	                    dd                    }|r&|||<   t                              d%| d&| d.           n4# t          $ r'}t                              d/|            Y d}~nd}~ww xY w|rNt                              d0t!          |           d1|            | j                             d|id2d|ii           t                              d3t!          |           d4|            |S # t          $ r5}t                              d5t          |                      Y d}~dS d}~ww xY w)6zRetrieve all status values for test cases in a document
        
        Args:
            url_key: The unique URL key for the document
            force_refresh: If True, forces a direct database query to get fresh data
        r/  r3   r  r  Nrd   zSTATUS DICT in MongoDB: z"NO STATUS DICT in MongoDB documentr+  ru  r  StatuszSHARED VIEW TC[z
]: Title='z', Status=''z] is not a dict: r   r   zMAIN VIEW TC[r   )parse_traditional_formatz	] parsed[z%] is a string but could not be parsedzError parsing MAIN VIEW TC[z] string entry: z'test_data is stored as string (length: z):    z...zFound z# status values in status dictionaryz.Building status values from shared view formatz,Building status values from main view formatz3Error parsing string test case entry in main view: z3Building status values from nested test_data formatzFound status 'z' for 'z' in nested test_datazEtest_data is stored as string - no individual status values availablez-Building status values from test_cases stringz' in parsed test_casesz!Error parsing test_cases string: z+Building status values from test_cases listrw  z' from list itemzError parsing test_cases list: z%UPDATING status dict in MongoDB with z	 values: rT   z
Returning z status values for z*Error retrieving test case status values: )r   r>   r   r   r7  r   rf   r  r  rV   r  r%   utils.file_handlerr  r&   r$   r   debugrX   )r'   r/  force_refreshrQ   r   rG  r   rd   r  parsedpidxptcptitlepstatusr(   r5  parsed_test_casestest_case_objrw  s                      r)   get_test_case_status_valuesz(MongoHandler.get_test_case_status_values  sI   t	
 _--y'.BCCF  115'2BCC  KK C' C CDDDDNN#VW#V#VWWW4 6!!Ivh7GIIJJJJ@AAA f$$F;4G)N)N$&vk':;; Y YEAr!"d++ Y "w 3 3!#"!5!5  d"KK(b!(b(bu(b(bY_(b(b(bccc'W'W'WTRTXX'W'WXXXXY &&:f[6I4+P+P&UaeklwexUxUx&vk':<'HII W WEAr!"d++ W "ww0C0C D D!#"&&22F2F!G!G  b"KK(`(`(`U(`(`W](`(`(`aaa#B,, W_SSSSSS%=%=b%A%AF% i1:61B1B ! !ID#-0WWWcgggr>R>R-S-SF.1gghRT@U@U.V.VG'- %(.4}A4}4}PT4}4}`f4}4}sz4}4}4}(~(~(~	! !'/gq/g/g/g h h h( _ _ _"LL)]q)])]Z[)])]^^^^^^^^_ 'Uq'U'U4PR88'U'UVVVV-W2 &&:f[6I3+O+O&   EVT_M`IaIa   E   Eflmxfyz~{~z~f   E   E   E  F  F  F	 6!!fX&6!_S)9%:%:___```h'' M f$$F;4G)N)N$LMMM - : :B!"d++ :2 "w 3 3!#"!5!5  :39M%0: &&:f[6I4+P+P&UaeklwexUxUxJKKK -l; d dB!"d++ d "ww0C0C D D!#"&&22F2F!G!G  :39M%0#B,, dOOOOOO
d0H0H0L0L-0 L+< !L !LC'1#t'<'< %L14#'''SUBVBV1W1W25''(CGGHVXDYDY2Z2Z+1 )LDKM&,A( d d d"LL)b_`)b)bccccccccddd. &&:f[6I4+P+P&U`djkvdwUwUwQRRRf[1+>EE k$[1+> k k%b$// k$&FF7BFF7B4G4G$H$HE%'VVHbffXr6J6J%K%KF$ k7=e 4 &-if-i-iU-i-i-i j j j &&:f[6I3+O+O&cddd	 &&:f[6I4+P+P&UaeklwexUxUxf[1,?EE NKK OPPPKKKKKKN,D,DVKEXYeEf,g,g), t&7 t t#-b$#7#7 !t,.FF7BFF7B<O<O,P,PE-/VVHbffXr>R>R-S-SF', %t?Ee(<(.5rf5r5rUZ5r5r5r(s(s(s$ N N N%L%L%LMMMMMMMMNN" &&:f[6I4+P+P&UaeklwexUxUxf[1,?FF LKK MNNNKKKKKKL-3K-@-N z zM)->> z9P]C]C]*7	*B#* 	!zz'3/G/G 	!z8P8PQX8Y8Y$5'8 %z2C )z )zB/9"d/C/C -z8:wwXZH[H[8\8\9;"&&QY[]J^J^9_9_38 1zKQM%4H4:LLAxRXAxAxafAxAxAx4y4y4yz % L L L%Jq%J%JKKKKKKKKL  pCDVDVppanppqqq**(h67  
 KKUS%7%7UUGUUVVV   	 	 	LLNc!ffNNOOO44444	s   A7l6 ;Hl6 CMl6 
M< M71l6 7M<<Bl6 Al6 E7l6 BYl6 
ZZ :l6  ZE
l6 A.l6 ?B/c0 .l6 0
d":dl6 d""A3l6 C,j l6 
j4j/*l6 /j44Bl6 6
m5 *m00m5c                    	 t          t          j                              dd         }||t          j                    dd}| j                            |           t                              d|            |S # t          $ r>}t          
                    dt          |                      t          d          d}~ww xY w)z,Save URL parameters and generate a short keyN   shortened_url)r3   
url_paramsr7   r  z,Successfully saved URL data with short key: zError saving URL data: z#Failed to save URL data to databaser0  )r'   r  	short_keyr2  r(   s        r)   save_url_datazMongoHandler.save_url_dataN  s    	CDJLL))"1"-I (&o//'	 H O&&x000KKRyRRSSS 	C 	C 	CLL;3q66;;<<<ABBB	Cr  c                    	 | j                             d|i          }|r4d|v r|                    d          S d|v r|                    d          S |S dS # t          $ r(}t                              d|            Y d}~dS d}~ww xY w)z6
        Retrieve URL parameters by short key
        r3   r+  r  NzError retrieving URL data: )r   r>   rV   r&   r   r$   )r'   r  r2  r(   s       r)   get_url_datazMongoHandler.get_url_data_  s    	//	0BCCH $(**#<<444!X--#<<555 $O4 	 	 	LL:q::;;;44444	s"   6A A A 
B BB)r+   )r   )Nr   )r   )rb   r   )r  r  )NNr  )NN)Nr  )Nr  )r  )r  )r   )NNN)NNrG  NN)F)[__name__
__module____qualname__r*   rL   rR   rZ   r_   rj   rt   ry   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r'  rE  rd  rr  r}  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r4  rF  rz  r  r  r  r=  r6  r7  r8  rr  r  r  r  r  r  r  r  r  r  r  r  rB  rI  ru  rl  r  r  r  r  rY   r)  r-  r3  r6  r>  rE  rn  rr  r  r  r  r  r  r   r   r)   r   r      sx       d d d'J 'J 'J 'JRP P P((J (J (JT	 	 	 M  M  MDO O O6Q Q Q0J J J J&J J J0#W #W #WJL L L0%M %M %MNN N N>M M M6"Q "Q "QHQ Q Q2-M -M -M^!K !K !K !KFU U U UB/R /R /Rb,O ,O ,O ,O\KV KV KVZ4W 4W 4Wl<M <M <M <M|EU EU EUN^V ^V ^V@/J /J /Jb7Q 7Q 7Qr'S 'S 'SR S  S  SD U  U  UD9T 9T 9TvFJ FJ FJPOL OL OL OLbYK YK YK YKv1X 1X 1XfN N N N0S S S S@O O O O8$U $U $U $ULQ Q Q Q<"U "U "U "UHI[ I[ I[ I[VX\ X\ X\t|X |X |X |X|mZ mZ mZ mZ^}X }X }X }X~\U \U \U \U|WZ WZ WZ WZrzY zY zY zYxu] u] u] u]n& & &	 	 		 	 	NY NY NY NY`Z] Z] Z] Z]xL\ L\ L\ L\\p
 p
 p
d# # #&
 
 
@~_ ~_ ~_ ~_@2 2 2h  >$ $ $L7
 7
 7
r
 
 
.>P >P >P@>V >V >V@! ! !FHY HY HY HYT  <KT KT KTZ  ]W ]W ]W ]W~9Y 9Y 9Yv   N N N<   D D D D*  "  (  8J J J JX   8] ] ]~J J J { { { {zC C C"    r   r   )utils.error_loggerr   r   r   r   r    r   r  r	   r   r   r   r   stringrandomloggingconfig.settingsr   r   rD   r@   r!  r  	getLoggerr  r   r   r   r   r)   <module>r     sG   W W W W W W W W W W W W               ( ( ( ( ( ( ( (     3 3 3 3 3 3 3 3   



 				 ( ( ( ( ( ( ( (		8	$	$\] \] \] \] \] \] \] \] \] \]r   