U
    hJ                    @   s   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eZG dd dZdS )	    )capture_exceptioncapture_messageset_tagset_contextN)MongoClientObjectIddatetime	timedelta)MONGODB_URI
MONGODB_DBc                   @   s  e Zd Zdd ZdddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dddZdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zdd'd(Zdd+d,Zd-d. Zdd0d1Zd2d3 Zd4d5 Zdd8d9Zd:d; Zd<d= Zd>d Zd?d@ ZdAdB ZdCdD Z dEdF Z!dGdH Z"dIdJ Z#ddLdMZ$ddNdOZ%dPdQ Z&ddRdSZ'ddUdVZ(ddWdXZ)ddYdZZ*dd[d\Z+dd]d^Z,dd`daZ-dbdc Z.ddddeZ/ddfdgZ0ddhdiZ1ddkdlZ2ddmdnZ3ddodpZ4ddqdrZ5dsdt Z6dudv Z7dwdx Z8ddydzZ9dd{d|Z:dd}d~Z;dd Z<dd Z=dd Z>dddZ?dd Z@dd ZAdd ZBdd ZCdd ZDdd ZEdd3 Zdd ZFdddZGdd ZHdd ZIdd ZJdddZKdd ZLdd ZMdd ZNdddZOdddZPdd ZQdd ZRdd ZSdddZTdddZUdd ZVdd ZWdddZXdd ZYdd ZZd)S )MongoHandlerc              
   C   s   zZt tdd| _| j  | jt | _| jj| _| jj| _	| jj
| _| jj| _td W nJ tjjtjjfk
r } z tdt|  tdW 5 d }~X Y nX d S )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e r&   @/var/www/html/testcasegenerator.evdpl.com/utils/mongo_handler.py__init__   s    




zMongoHandler.__init__userc           
   
   C   s   z| j d| i}|r&dddW S t }t|d|}tt	 | |||t
 ddd}| j | td	| d
|  dd|d |d |d |d ddW S  tk
r }	 z&tdt|	  ddd W Y S d}	~	X Y nX dS )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 successfullyr0   r2   r3   idr*   r2   r3   )r-   r.   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*   r1   r2   r3   existing_usersalthashed_passworduser_docr%   r&   r&   r'   create_user&   s8    
zMongoHandler.create_userc              
   C   s   z`| j ddi}|r"dddW S | j|||dd}|d rXtd|  d	d
dW S |W S W nD tk
r } z&tdt|  ddd W Y S d}~X Y nX dS )z:Create the initial admin user (should only be called once)r3   adminFzAdmin user already existsr,   )r3   r-   z!Successfully created admin user: TzAdmin user created successfullyzError creating admin user: Failed to create admin userN)r   r;   rI   r   r   r#   r!   r"   )r$   r*   r1   r2   existing_adminresultr%   r&   r&   r'   create_admin_userO   s    
zMongoHandler.create_admin_userc              
   C   s  z| j d| i}|s&dddW S |dds>dddW S t|d|d	 r| j d
|d
 iddt	 ii | 
|d
 }td|  dd|d
 |d |d |ddd|dW S dddW S W nF tk
r } z&tdt|  ddd W Y S d}~X Y nX dS )zAuthenticate user loginr*   FzInvalid email or passwordr,   r6   TzAccount is deactivatedr/   r1   r0   $setr5   z!Successfully authenticated user: zLogin successfulr2   r3   r)   r8   )r-   r.   r)   tokenzError authenticating user: zAuthentication failedN)r   r;   r<   getr=   checkpwr@   
update_oner
   rC   generate_jwt_tokenr   r   r#   r!   r"   )r$   r*   r1   r)   rP   r%   r&   r&   r'   authenticate_userc   s4    

zMongoHandler.authenticate_userc              
   C   sx   z6| j d|i}|r2|ddr2|ddkW S W dS  tk
rr } ztdt|  W Y dS d}~X Y nX dS )	zCheck if a user is an adminr0   r6   Tr3   rJ   FzError checking admin status: Nr   r;   rQ   r#   r   r!   r"   r$   user_idr)   r%   r&   r&   r'   is_admin   s    zMongoHandler.is_adminc                 C   s   z|  |sdddW S t| ji ddddddddd}|D ]X}d|kr\t|d |d< d|krt|d  |d< d|kr@|d r|d  nd	|d< q@d
|dW S  tk
r } z&tdt|  ddd W Y S d	}~X Y nX d	S )zGet all users (admin only)F)Access denied. Admin privileges required.r,      r0   r*   r2   r3   statusr4   r5   r6   r0   r4   r5   NT)r-   r   zError getting all users: Failed to retrieve users)	rY   listr   findr"   	isoformatr#   r   r!   )r$   admin_user_idr   r)   r%   r&   r&   r'   get_all_users   s0    


zMongoHandler.get_all_usersc              
   C   s   z|  |sdddW S |dkr,dddW S | jd|idd|ii}|jd	krxtd
| d|  dd
| dW S dddW S W nD tk
r } z&tdt|  ddd W Y S d}~X Y nX dS )zUpdate user role (admin only)FrZ   r,   rJ   r)   'Invalid role. Must be 'admin' or 'user'r0   rO   r3   r   User role updated to 
 by admin Tz User not found or role unchangedzError updating user role: zFailed to update user roleN	rY   r   rS   modified_countr   r   r#   r!   r"   )r$   rb   target_user_idnew_rolerM   r%   r&   r&   r'   update_user_role   s     


zMongoHandler.update_user_rolec              
   C   s   z|  |sdddW S | jd|idd|ii}|jdkrr|rDdnd	}td
| d|  dd
| ddW S dddW S W nD tk
r } z&tdt|  ddd W Y S d}~X Y nX dS )z&Toggle user active status (admin only)FrZ   r,   r0   rO   r6   r   Z	activatedZdeactivatedzUser rg   Tz successfullyz"User not found or status unchangedzError toggling user status: zFailed to update user statusNrh   )r$   rb   rj   r6   rM   Zstatus_textr%   r&   r&   r'   toggle_user_status   s    


zMongoHandler.toggle_user_statusc              
   C   s   zf|  |sdddW S | ||||}|d r^td| d| d|  dd	| dW S |W S W nD tk
r } z&td
t|  ddd W Y S d}~X Y nX dS )z"Create a new user account by adminFrZ   r,   r-   zUser created by admin : z with role Tz$User created successfully with role Error creating user by admin: r:   N)rY   rI   r   r   r#   r!   r"   )r$   rb   r*   r1   r2   r3   rM   r%   r&   r&   r'   create_user_by_admin   s    

z!MongoHandler.create_user_by_adminc              
   C   s   zv|  |sdddW S ||kr,dddW S | jd|i}|jdkrhtd| d|  d	d
dW S dddW S W nD tk
r } z&tdt|  ddd W Y S d}~X Y nX dS )zDelete a user (admin only)FrZ   r,   zCannot delete your own accountr0   r   zUser deleted by admin rn   TzUser deleted successfullyUser not foundzError deleting user: zFailed to delete userN)	rY   r   
delete_onedeleted_countr   r   r#   r!   r"   )r$   rb   rj   rM   r%   r&   r&   r'   delete_user   s    

zMongoHandler.delete_userc              
   C   s   z|  |sdddW 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	d}| jdd|ii}	|||| |||	d}
d|
dW S  tk
r } z&t	dt
|  ddd W Y S d}~X Y nX dS )z Get user statistics (admin only)FrZ   r,   r6   Tr3   rJ   r)   r   r	   r[   dayhourminutesecondmicrosecondr4   $gte)total_usersactive_usersZinactive_usersadmin_usersregular_usersnew_users_this_month)r-   
statisticszError getting user statistics: z"Failed to retrieve user statisticsN)rY   r   count_documentsr
   r   rC   replacer#   r   r!   r"   )r$   rb   r|   r}   r~   r   r
   r   	first_dayr   statsr%   r&   r&   r'   get_user_statistics  s*    
	z MongoHandler.get_user_statisticsc              
   C   s   z| j d|iddi}|r|d|kr4t|d |d< d|krL|d  |d< d|krp|d rh|d  nd|d< d|dW S d	d
dW S W nD tk
r } z&tdt|  d	dd W Y S d}~X Y nX dS )zGet user details by IDr0   r1   r   r4   r5   NTr-   r)   Frq   r,   zError getting user by ID: zFailed to retrieve user)r   r;   r"   ra   r#   r   r!   rW   r&   r&   r'   get_user_by_id=  s"     zMongoHandler.get_user_by_idc              
      s*  z| j d|i}|s"dddW S |ddkrD||krDdddW S dd	g |ddkrh dd	g  fd
d| D }|sdddW S | j d|id|i}|jdkrtd| d|  dddW S dddW S W nF t	k
r$ } z&t
dt|  ddd W Y S d}~X Y nX dS )zYUpdate user profile (admin can update any user, regular users can only update themselves)r0   FzCurrent user not foundr,   r3   rJ   z4Access denied. You can only update your own profile.r2   r*   c                    s   i | ]\}}| kr||qS r&   r&   ).0kvZallowed_fieldsr&   r'   
<dictcomp>g  s       z4MongoHandler.update_user_profile.<locals>.<dictcomp>zNo valid fields to updaterO   r   zUser profile updated by rn   TzProfile updated successfullyzNo changes madezError updating user profile: zFailed to update profileN)r   r;   rQ   extenditemsrS   ri   r   r   r#   r!   r"   )r$   Zcurrent_user_idrj   updatescurrent_userZfiltered_updatesrM   r%   r&   r   r'   update_user_profileU  s.    
z MongoHandler.update_user_profilec           	   
   C   s   z| j d|i}|s"dddW S t|d|d sDdddW S t }t|d|}| j d|idd|ii}|jd	krt	
d
|  dddW S dddW S W nD tk
r } z&t	dt|  ddd W Y S d}~X Y nX dS )zChange user passwordr0   Frq   r,   r/   r1   zCurrent password is incorrectrO   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=   rR   r@   r>   r?   rS   ri   r   r   r#   r!   r"   )	r$   rX   Zcurrent_passwordnew_passwordr)   rF   hashed_new_passwordrM   r%   r&   r&   r'   change_password|  s&    

zMongoHandler.change_passwordc              
   C   s   z|  |sdddW S t }t|d|}| jd|idd|ii}|jdkrxt	d	| d
|  dddW S dddW S W nD t
k
r } z&tdt|  ddd W Y S d}~X Y nX dS )zReset user password by adminFrZ   r,   r/   r0   rO   r1   r   zPassword reset by admin z for user: TPassword reset successfullyrq   z#Error resetting password by admin: Failed to reset passwordN)rY   r=   r>   r?   r@   r   rS   ri   r   r   r#   r!   r"   )r$   rb   rj   r   rF   r   rM   r%   r&   r&   r'   reset_password_by_admin  s     


z$MongoHandler.reset_password_by_adminc              
   C   s   zddl }ddl}ddlm}m} |d}||  }| |dd }|||| dd}	| j	j
|	}
|
jrtd	|  d
||dW S dddW S W nD tk
r } z&tdt|  ddd W Y S d}~X Y nX dS )z1Create a password reset token for the given emailr   Nr	       r[   hoursF)r*   
token_hash
expires_atr4   usedz(Password reset token created for email: T)r-   rP   r   zFailed to create reset tokenr,   z%Error creating password reset token: )secretshashlibr
   r   token_urlsafesha256r@   	hexdigestrC   r   password_reset_tokensrD   inserted_idr   r   r#   r!   r"   )r$   r*   r   r   r
   r   rP   r   r   Z
reset_datarM   r%   r&   r&   r'   create_password_reset_token  s*    
	z(MongoHandler.create_password_reset_tokenc              
   C   s   zhddl }ddlm} ||  }| jj|dd| id}|rZd|d d	W S dd
dW S W nD t	k
r } z&t
dt|  ddd W Y S d}~X Y nX dS )z<Verify a password reset token and return user email if validr   Nr
   F$gtr   r   r   Tr*   )r-   r*   Invalid or expired reset tokenr,   z&Error verifying password reset token: zFailed to verify reset token)r   r
   r   r@   r   r   r   r;   rC   r#   r   r!   r"   )r$   rP   r   r
   r   reset_recordr%   r&   r&   r'   verify_password_reset_token  s    
z(MongoHandler.verify_password_reset_tokenc              
   C   s8  zddl }ddlm} ||  }| jj|dd| id}|sVdddW S |d	 }t	
 }t	|d
|}	| jd	|idd|	ii}
|
jdkr| jjd|d idd| di td|  dddW S dddW S W nF tk
r2 } z&tdt|  ddd W Y S d}~X Y nX dS )z-Use a password reset token to change passwordr   Nr   Fr   r   r   r,   r*   r/   rO   r1   r0   T)r   Zused_atz'Password reset successfully for email: r   rq   z"Error using password reset token: r   )r   r
   r   r@   r   r   r   r;   rC   r=   r>   r?   r   rS   ri   r   r   r#   r!   r"   )r$   rP   r   r   r
   r   r   r*   rF   r   Zuser_resultr%   r&   r&   r'   use_password_reset_token  s:    



z%MongoHandler.use_password_reset_token   c              
   C   s  z|  |sdddW S dd|ddid|ddigi}t| j|d	d
i|}|D ]X}d|krtt|d |d< d|kr|d  |d< d|krX|d r|d  nd|d< qXd|t|dW S  tk
r } z&t	
dt|  ddd W Y S d}~X Y nX dS )z*Search users by name or email (admin only)FrZ   r,   z$orr2   i)z$regexz$optionsr*   r1   r   r0   r4   r5   NT)r-   r   countzError searching users: zFailed to search users)rY   r_   r   r`   limitr"   ra   lenr#   r   r!   )r$   rb   queryr   Zsearch_queryr   r)   r%   r&   r&   r'   search_users"  s2    

 zMongoHandler.search_usersN2   c              
   C   s   z|  |sdddW S i }|r(||d< t| j|ddddddd|}|D ]4}d	|krrt|d	 |d	< d|krV|d  |d< qVd
|t|dW S  t	k
r } z&t
dt|  ddd W Y S d}~X Y nX dS )z#Get user activity logs (admin only)FrZ   r,   rX   r[   )rX   r4   source_typer]   r4   r0   T)r-   logsr   z"Error getting user activity logs: z Failed to retrieve activity logsN)rY   r_   r   r`   sortr   r"   ra   r   r#   r   r!   )r$   rb   rX   r   r   r   logr%   r&   r&   r'   get_user_activity_logsE  s4    

 z#MongoHandler.get_user_activity_logsc           
   
   C   sL   z|  |sdddW S t|ts0dddW S d}g }|D ]}|d}|d}|r\|sn|d|  q<|d	kr|d
| d|  q<| jd|idd|ii}|jdkr|d7 }t	d| d| d|  q<|d|  q<dd| d||dW S  t
k
rF }	 z&tdt|	  ddd W Y S d}	~	X Y nX dS )z#Bulk update user roles (admin only)FrZ   r,   z.Invalid format. Expected list of user updates.r   rX   r3   z$Missing user_id or role for update: rd   zInvalid role 'z' for user r0   rO   r[   rf   rg   rn   zFailed to update role for user TzBulk update completed. z users updated.)r-   r.   updated_countr   z!Error in bulk update user roles: zFailed to perform bulk updateN)rY   
isinstancer_   rQ   appendr   rS   ri   r   r   r#   r!   r"   )
r$   rb   Zuser_updatesr   r   updaterX   rk   rM   r%   r&   r&   r'   bulk_update_user_rolesf  s@    






z#MongoHandler.bulk_update_user_rolesjsonc              
   C   sn  z |  |sdddW S t| ji ddi}|D ]X}d|krPt|d |d< d|krh|d  |d< d|kr4|d r|d  nd	|d< q4|d
krd|d
dW S |dkrdd	l}dd	l}| }|r|d 	 }|j
||d}	|	  |	| | }
|  d|
ddW S dddW S W nF tk
rh } z&tdt|  ddd W Y S d	}~X Y nX d	S )zExport user data (admin only)FrZ   r,   r1   r   r0   r4   r5   Nr   T)r-   dataformatcsv)
fieldnameszUnsupported format typezError exporting user data: zFailed to export user data)rY   r_   r   r`   r"   ra   r   ioStringIOkeys
DictWriterwriteheader	writerowsgetvaluecloser#   r   r!   )r$   rb   format_typer   r)   r   r   outputr   writerZcsv_datar%   r&   r&   r'   export_user_data  s@    

 

zMongoHandler.export_user_datac              
   C   s@  z| j d|i}|s$dddW S t| jd|idddddddd	d
}|D ]4}d|krtt|d |d< d|krX|d  |d< qX| j	d|i}ddl
m
}m} | jdddddd}| j	|d|id}	| jd|idddd}
|
r0d|
krt|
d |
d< d|
kr0|
d  |
d< |d |d |d |dd|drd|d  nd|dr~|d  ndd||	|
d|d}|ddkr| |}|d r|d |d< | j|d
d}|d r|d |d < d!|d"W S  tk
r: } z&td#t|  dd$d W Y S d}~X Y nX dS )%.Get user dashboard data with role-based accessr0   Frq   r,   rX   r[   r0   titler4   r   r]   r4   r   
   r   r	   ru   r{   rX   r4   )r0   r   r4   r2   r*   r3   r)   Nr5   r9   r2   r*   r3   r4   r5   total_test_cases
this_monthlast_generated)	user_infor   recent_test_casesrJ   r-   r   Zadmin_statistics)r   r   recent_activityTr-   dashboard_data#Error getting user dashboard data: !Failed to retrieve dashboard data)r   r;   r_   r   r`   r   r   r"   ra   r   r
   r   rC   r   rQ   r   r   r#   r   r!   )r$   rX   r)   user_test_cases	test_caser   r
   r   r   this_month_countr   r   Zadmin_statsr   r%   r&   r&   r'   get_user_dashboard_data  st     



	


z$MongoHandler.get_user_dashboard_datac              
   C   sB  z|  |sdddW S | ji }| ji }| ji }t| ji ddddddddd}|D ]4}d	|krt	|d	 |d	< d|krl|d 
 |d< ql| |}|d
 |d |d d}|||||d r|di ni |dd}	d|	dW S  tk
r< }
 z&tdt	|
  ddd W Y S d}
~
X Y nX dS )z Get system overview (admin only)FrZ   r,   r[   )r0   r   r4   rX   r   r4   r   r   r0   i   i   i   )Ztest_cases_sizeZ
users_sizeZanalytics_sizer-   r   healthy)r   r|   total_analyticsr   user_statisticsstorage_infosystem_healthT)r-   system_overviewzError getting system overview: z"Failed to retrieve system overviewN)rY   r   r   r   r   r_   r`   r   r   r"   ra   r   rQ   r#   r   r!   )r$   rb   r   r|   r   r   r   
user_statsr   r   r%   r&   r&   r'   get_system_overview  sP    

 	

z MongoHandler.get_system_overviewr[   r   c                 C   s  zH|  |sdddW S |d | }| ji }t| ji ddddddddddd||}|D ]}d|krt|d |d< ztd	d
l	m	} d|krt
|d |r|d  |d< d|kr|d dkst
|d |r|d r|d  nd|d< W qn tk
r   Y qnX qn|| d | }	d|||||	||	k |dkddW S  tk
r }
 z&tdt|
  ddd W Y S d}
~
X Y nX dS )z*Get all users with pagination (admin only)FrZ   r,   r[   r\   r4   r   r0   r   r   r5   NT)Zcurrent_pageper_pager|   total_pageshas_nextZhas_prev)r-   r   Z
paginationzError getting paginated users: r^   )rY   r   r   r_   r`   r   skipr   r"   r
   r   ra   r#   r   r!   )r$   rb   pager   r   r|   r   r)   _dtr   r%   r&   r&   r'   get_all_users_paginatedH  s^    


 

" z$MongoHandler.get_all_users_paginatedc                 C   s  z|  |sdddW S d}z| jd W n tk
rF   d}Y nX i }ddd	g}|D ]}zJ|dkrp| j}n|dkr| j}n|d	kr| j}|i }d|d
||< W qZ tk
r } zdt|d||< W 5 d}~X Y qZX qZddl	m	}	m
}
 |	 |
dd }| jdd|ii| jdd|ii| jdd|iid}d}|dkrRd}ntdd | D rnd}d|||||	  ddW S  tk
r } z&tdt|  ddd W Y S d}~X Y nX dS )%Get system health status (admin only)FrZ   r,   r   ping	unhealthyr   r   r   r]   Zdocument_count)r]   r!   Nr   r	   r[   daysr4   r{   r5   )Znew_users_24hZnew_test_cases_24hZactive_users_24hcriticalc                 s   s   | ]}|d  dkV  qdS )r]   r   Nr&   )r   colr&   r&   r'   	<genexpr>  s     z1MongoHandler.get_system_health.<locals>.<genexpr>warningT)overall_statusZdatabase_statuscollections_statusr   	timestamp)r-   r   zError getting system health: z Failed to retrieve system health)rY   r   commandr#   r   r   r   r   r"   r
   r   nowanyvaluesra   r   r!   )r$   rb   	db_statusr  collectionscollection_namer   r   r%   r
   r   	yesterdayr   Zoverall_healthr&   r&   r'   get_system_health  s`    





zMongoHandler.get_system_healthc              
   C   s  z|  |sdddW S ddlm}m} | ji }| jddi}| jddi}| jd	d
i}| |dd }| 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 ]P}d|kr
t	|d |d< d%|kr$t	|d% |d%< d&|kr|d& 
 |d&< qdd'ddid(ig}t| j|}d
|||||	d)|d*d+ || 
 d,d-W S  tk
r } z&td.t	|  dd/d W Y S d*}~X Y nX d*S )0z(Get detailed user analytics (admin only)FrZ   r,   r   r	   r3   rJ   r)   r6   T   r   r4   r{   $group$user_id$sumr[   $max$created_at)r0   test_case_countlast_activityz$lookupr   r0   r   )fromZ
localFieldZforeignFieldas$unwindz
$user_info$project$_idz$user_info.namez$user_info.email)rX   Z	user_nameZ
user_emailr  r  $sortr  r   rX   r  $source_typer0   r   )r|   r~   r   r}   users_created_30dNr   )r   user_activitysource_distributionZgenerated_at)r-   r   z'Error getting detailed user analytics: z!Failed to retrieve user analytics)rY   r
   r   r   r   r  r_   r   	aggregater"   ra   r#   r   r!   )r$   rb   r
   r   r|   r~   r   r}   Zthirty_days_agor  pipeliner  activityZsource_pipeliner  r%   r&   r&   r'   get_detailed_user_analytics  s    
	 
 !

	

z(MongoHandler.get_detailed_user_analyticsc           
   
   C   s6  z|  |sdddW S dddg}|D ]*}||ks:|| s&dd| d  W S q&| jd|d i}|rvdddW S | |d }|d |d ||d	d
|ddt ddd}| j|}|jrddt	|jdW S dddW S W nF t
k
r0 }	 z&tdt	|	  ddd W Y S d}	~	X Y nX dS )z'Create a new user by admin (admin only)FrZ   r,   r2   r*   r1   zMissing required field: r+   r3   r)   r6   TNactive)r2   r*   r1   r3   r6   r4   r5   r]   r7   )r-   r.   rX   r:   ro   )rY   r   r;   hash_passwordrQ   r
   r  rD   r   r"   r#   r   r!   )
r$   rb   	user_datarequired_fieldsfieldrE   rG   rH   rM   r%   r&   r&   r'   rp   -  s<    



c              
   C   s  zl|  |sdddW S ddlm} t| ji ddi}|D ]X}d|kr\t|d |d< d|krt|d  |d< d	|kr@|d	 r|d	  nd
|d	< q@t| ji }|D ]4}d|krt|d |d< d|kr|d  |d< qt| ji }|D ]6}d|krt|d |d< d|kr|d  |d< q|	  |dd|||t
|t
|t
|dd}	d|	dW S  tk
r }
 z&tdt|
  ddd W Y S d
}
~
X Y nX d
S )zExport system data (admin only)FrZ   r,   r   r   r1   r0   r4   r5   Nr  z1.0)Zexported_atZexported_byversion)r|   r   r   )Zexport_infor   r   r   r   T)r-   r   zError exporting system data: zFailed to export system data)rY   r
   r_   r   r`   r"   ra   r   r   r  r   r#   r   r!   )r$   rb   r
   r   r)   r   r   r   analyticZexport_datar%   r&   r&   r'   export_system_data^  sP    


zMongoHandler.export_system_datac              
   C   s   z|  |sdddW S t  ddddt tdd	  dd
ddt tdd	  ddddt tdd	  ddddg}d|dW S  tk
r } z&tdt|  ddd W Y S d}~X Y nX dS )zGet system logs (admin only)FrZ   r,   r   zSystem started successfullySystem)r  levelr.   sourcer[   r   zUser authentication successfulAuth   r   High memory usage detected   r!   zDatabase connection timeoutDatabaseT)r-   r   zError getting system logs: zFailed to retrieve system logsN)	rY   r
   r  ra   r   r#   r   r!   r"   )r$   rb   Z	mock_logsr%   r&   r&   r'   get_system_logs  s8    

zMongoHandler.get_system_logsc              
   C   s   zf|  |sdddW S ddlm} |  |dd| ji | ji | ji d}d	d
|dW S  tk
r } z&t	
dt|  ddd W Y S d}~X Y nX dS )z!Create system backup (admin only)FrZ   r,   r   r   full)r4   
created_bybackup_type)backup_infoZusers_countZtest_cases_countZanalytics_countTz"System backup created successfully)r-   r.   r7  zError creating system backup: zFailed to create system backupN)rY   r
   r  ra   r   r   r   r   r#   r   r!   r"   )r$   rb   r
   backup_datar%   r&   r&   r'   create_system_backup  s&    




z!MongoHandler.create_system_backupc              
   C   s   zt|  |sdddW S ttttttd}| D ]4\}}||kr2t|| |s2dd| d  W S q2dd|dW S  tk
r } z&td	t|  dd
d W Y S d}~X Y nX dS )z#Update system settings (admin only)FrZ   r,   )ZenableRegistrationZrequireEmailVerificationZmaxTestCasesZsessionTimeoutZemailNotificationsZadminAlertszInvalid setting type for Tz$System settings updated successfully)r-   r.   settingsz Error updating system settings: z Failed to update system settingsN)	rY   boolintr   r   r#   r   r!   r"   )r$   rb   r:  Zvalid_settingskey
value_typer%   r&   r&   r'   update_system_settings  s(    
	z#MongoHandler.update_system_settingsc              
   C   s  z^|  |sdddW S ddlm} g }z||}|d|i W n tk
rX   Y nX |d|i ddddddddd}d	}|D ]}| j||}|r qq|sdd
dW S t|d |d< z|ddlm}	 d|krt	|d |	r|d 
 |d< d|kr<|d d	kst	|d |	r<|d r4|d 
 nd	|d< W n tk
rT   Y nX d|dW S  tk
r }
 z&tdt|
  ddd W Y S d	}
~
X Y nX d	S )zGet user details (admin only)FrZ   r,   r   r   r0   r[   r\   Nrq   r   r4   r5   Tr   zError getting user details: zFailed to retrieve user details)rY   bsonr   r   r#   r   r;   r"   r
   r   ra   r   r!   )r$   rb   rj   r   query_candidatesuser_object_id
projectionr)   qr   r%   r&   r&   r'   get_user_details  sP    
("zMongoHandler.get_user_detailsc              
   C   s&  z|  |sdddW S ddlm} g }z||}|d|i W n tk
rX   Y nX |d|i d}d}|D ]}	| j|	}|rt|	} qqt|sdddW S d	|kr|d	 sdd
dW S d|kr|d sdddW S d|kr|d |dkr| jd|d i}
|
rdddW S d|krB|d dkrBdddW S i }d	|kr\|d	 |d	< d|krr|d |d< d|kr|d |d< d|krt|d |d< | j	|d|i}|j
dkrdddW S dddW S W nF tk
r  } z&tdt|  ddd W Y S d}~X Y nX dS )z!Update user by admin (admin only)FrZ   r,   r   r   r0   Nrq   r2   zName cannot be emptyr*   zEmail cannot be emptyzEmail already existsr3   rd   re   r6   rO   TzUser updated successfullyzNo changes made to userzError updating user by admin: zFailed to update user)rY   r@  r   r   r#   r   r;   rQ   r;  rS   ri   r   r!   r"   )r$   rb   rj   r%  r   rA  rB  rE   Zchosen_queryrD  Zemail_existsZupdate_datarM   r%   r&   r&   r'   update_user_by_admin?  s`    




z!MongoHandler.update_user_by_adminr4  c                 C   s,  z|  |sdddW S i }|dkrt| ji ddi}|D ]X}d|kr\t|d |d< d|krt|d  |d< d	|kr@|d	 r|d	  nd
|d	< q@||d< |dkrt| ji ddddddd}|D ]4}d|krt|d |d< d|kr|d  |d< q||d< |dkr|t| ji ddddd}|D ]:}	d|	krVt|	d |	d< d|	kr8|	d  |	d< q8||d< |t	  |t
|dg t
|dg t
|dg d|d< td| d| d d|dW S  tk
r& }
 z&tdt|
  ddd W Y S d
}
~
X Y nX d
S )zBackup user data (admin only)FrZ   r,   r4  r   r1   r   r0   r4   r5   Nr   r4  r   r[   )r0   r   r4   rX   r   r]   r   r4  r   )r0   r4   typer   r   )r6  r4   r5  r|   r   r   metadatazBackup created by admin rn   z backupT)r-   r8  zError creating backup: zFailed to create backup)rY   r_   r   r`   r"   ra   r   r   r
   rC   r   rQ   r   r   r#   r!   )r$   rb   r6  r8  r   r)   r   r   r   r)  r%   r&   r&   r'   backup_user_data  sr    

 










	zMongoHandler.backup_user_datac              
   C   s   z|  |sdddW S t|tr,d|kr8dddW S d}g }|dkrd|krz|d D ]|}d	|kr|d	 rt|d	 |d	< d
|kr|d
 rt|d
 |d
< | j|}|jr|d7 }q^|d|	dd  q^W n8 t
k
r } z|dt|  W 5 d}~X Y nX |dkrd|krzp|d D ]b}	d	|	kr`|	d	 r`t|	d	 |	d	< | j|	}|jr~|d7 }n|d|		dd  q6W n8 t
k
r } z|dt|  W 5 d}~X Y nX |dkrd|krzb|d D ]T}
d	|
kr|
d	 rt|
d	 |
d	< | j|
}|jr<|d7 }n
|d qW n8 t
k
r } z|dt|  W 5 d}~X Y nX td| d| d dd| d||d W S  t
k
r } z&td!t|  dd"d W Y S d}~X Y nX dS )#z*Restore user data from backup (admin only)FrZ   r,   rK  zInvalid backup data formatr   rG  r   r4   r5   r[   zFailed to restore user: r*   UnknownzError restoring users: NrH  r   zFailed to restore test case: r   zError restoring test cases: rI  r   zError restoring analytic datazError restoring analytics: z$Data restoration completed by admin rn   z restoreTzRestoration completed. z items restored.)r-   r.   restored_countr   zError restoring data: zFailed to restore data)rY   r   dictr
   fromisoformatr   rD   r   r   rQ   r#   r"   r   r   r   r   r!   )r$   rb   r8  Zrestore_typerN  r   r)   rM   r%   r   r)  r&   r&   r'   restore_user_data  sf    

&
 &
&
zMongoHandler.restore_user_datac                 C   s   z| j d|i}|s"dddW 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
W S  tk
r } z&tdt|  ddd W Y S d}~X Y nX dS )z"Get user permissions based on roler0   Frq   r,   r3   r)   TZcan_create_usersZcan_delete_usersZcan_update_user_rolesZcan_view_all_usersZcan_view_system_statsZcan_backup_dataZcan_restore_dataZcan_export_dataZcan_manage_systemZcan_view_analyticsZcan_manage_test_casesrd   )r-   permissionsr3   z Error getting user permissions: #Failed to retrieve user permissionsNrV   )r$   rX   r)   r3   rS  Zuser_permissionsr%   r&   r&   r'   get_user_permissions3  sL    z!MongoHandler.get_user_permissionsc              
   C   s   z| j d|i}|s"dddW S |ddkr<dddW S |r| |}|d s^dd	dW S |d
 |dsdd| ddW S dddW S  tk
r } z&tdt|  ddd W Y S d}~X Y nX dS )zEValidate if user has admin access and specific permission if requiredr0   Frq   r,   r3   rJ   rZ   r-   rT  rS  zAccess denied. z permission required.TzAccess grantedzError validating admin access: zFailed to validate accessN)r   r;   rQ   rU  r#   r   r!   r"   )r$   rX   Zrequired_permissionr)   rS  r%   r&   r&   r'   validate_admin_accessf  s     
z"MongoHandler.validate_admin_accessd   c              
   C   s   zJ|  |sdddW S i }|r(||d< |r4||d< g }d|t|ddW S  tk
r } z&td	t|  dd
d W Y S d}~X Y nX dS )z!Get user audit trail (admin only)FrZ   r,   rX   action_typeTz'Audit trail feature not yet implemented)r-   
audit_logsr   r.   z Error getting user audit trail: zFailed to retrieve audit trailN)rY   r   r#   r   r!   r"   )r$   rb   rX   rX  r   r   rY  r%   r&   r&   r'   get_user_audit_trail~  s"    
z!MongoHandler.get_user_audit_trailc           	   
   C   s   zb||||t  ddd}| jj}||}|jrTtd| d|  dddW S dd	dW S W nD tk
r } z&t	d
t
|  ddd W Y S d}~X Y nX dS )z!Log admin actions for audit trailN)rb   rX  	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
   rC   r   Zadmin_audit_logsrD   r   r   r   r#   r!   r"   )	r$   rb   rX  r[  r\  Zaudit_entryZaudit_collectionrM   r%   r&   r&   r'   log_admin_action  s$    
zMongoHandler.log_admin_actionc                 C   s  z|  |sdddW S i }|r(||d< t| j|dddddddddd|}|D ]L}d	|krxt|d	 |d	< d
|kr|d
  |d
< d|kr\|d  |d< q\d|t|dW S  t	k
r  } z&t
dt|  ddd W Y S d}~X Y nX dS )z)Get user session information (admin only)FrZ   r,   rX   r[   )r0   rX   r4   r  r]  r^  r6   r  r   r0   r4   T)r-   sessionsr   zError getting user sessions: z Failed to retrieve user sessionsN)rY   r_   r   r`   r   r   r"   ra   r   r#   r   r!   )r$   rb   rX   r   r   r`  sessionr%   r&   r&   r'   get_user_sessions  s>    

 zMongoHandler.get_user_sessionsc              
   C   s   z|  |sdddW S i }|r(||d< |r4||d< | j|ddt di}|jdkrtd	| d
|j d d|j ddW S dddW S W nD tk
r } z&t	dt
|  ddd W Y S d}~X Y nX dS )z$Terminate user sessions (admin only)FrZ   r,   rX   r0   rO   )r6   Zterminated_atr   z"User sessions terminated by admin rn   z	 sessionsTz! sessions terminated successfullyzNo sessions found to terminatez!Error terminating user sessions: zFailed to terminate sessionsN)rY   r   update_manyr
   rC   ri   r   r   r#   r!   r"   )r$   rb   rX   
session_idr   rM   r%   r&   r&   r'   terminate_user_sessions  s&    

z$MongoHandler.terminate_user_sessionsc              
   C   s  z|  |sdddW S i }|r(||d< t| j|dddddddd|}|D ]X}d	|krtt|d	 |d	< d
|kr|d
  |d
< d|krX|d r|d  nd|d< qXd|t|dW S  t	k
r } z&t
dt|  ddd W Y S d}~X Y nX dS )z#Get user login history (admin only)FrZ   r,   rX   r[   )r0   r*   r2   r5   r4   r5   r   r0   r4   NT)r-   Zlogin_historyr   z"Error getting user login history: z Failed to retrieve login history)rY   r_   r   r`   r   r   r"   ra   r   r#   r   r!   )r$   rb   rX   r   r   r   r)   r%   r&   r&   r'   get_user_login_history  s:    

 	z#MongoHandler.get_user_login_historymonthc                 C   s  z|  |sdddW S ddlm}m} | }|dkrJ||dd }nV|d	krb||dd
 }n>|dkrz||dd }n&|dkr||dd }n||dd }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 ]x}| jd|d idddd}|rt	|d |d |d  |
d!d"|d# |
d$d|
d%dd& d'}|
| q|
jd(d) d*d+ d*|| | |
t|
d,W S  tk
r } z&td-t	|  dd.d W Y S d/}~X Y nX d/S )0z)Get user performance metrics (admin only)FrZ   r,   r   r	   rv   r[   r   weekweeksrg  r  yearm  r4   r{   rX   $matchr  r  r  $avg$completion_time$cond$eq$status	completed)r0   r   avg_completion_timesuccess_rater0   r2   r*   r3   r2   r*   r3   r)   r   rt  ru  rW  )rX   r2   r*   r3   r   rt  ru  c                 S   s   | d S )Nr   r&   xr&   r&   r'   <lambda>^      z;MongoHandler.get_user_performance_metrics.<locals>.<lambda>Tr=  reverse)r-   time_period
start_dateend_dateuser_metricsr|   z(Error getting user performance metrics: z&Failed to retrieve performance metricsN)rY   r
   r   rC   r_   r   r  r   r;   r"   rQ   r   r   ra   r   r#   r   r!   )r$   rb   rX   r}  r
   r   r  r~  r   Ztest_case_metricsr  metricr)   user_metricr%   r&   r&   r'   get_user_performance_metrics"  sl    



		z)MongoHandler.get_user_performance_metricsc                 C   sT  z|  |sdddW S z| j  d}W n0 tk
r\ } zdt| }W 5 d}~X Y nX i }dD ]f}z&| j| }|i }d|d||< W qf tk
r } zdt| d	d||< W 5 d}~X Y qfX qfd	dl}z4|jd
d}	|	 }
|
d}|	|
j|jdd}W n  tk
r*   ddd}Y nX d}|dkr>d}| D ]}|d dkrFd} qfqF|t  |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"W S  tk
rN } z&td#t|  dd$d W Y S d}~X Y nX dS )%r   FrZ   r,   r   zunhealthy: N)r   r   r   r   r   r   r[   )interval/Z	available)cpu_percentmemory_percentdisk_percentr]   zpsutil not availablez5Install psutil package for system resource monitoring)r]   r.   r   r]   ZMongoDB)r]   
connection)r   r  databaser  system_resourcesrecommendationsr  z/Check database connection and collection accessr  P   zHigh CPU usage detectedr  r0  r  Z   zLow disk space detectedT)r-   health_statusz$Error getting system health status: z'Failed to retrieve system health status)rY   r   r   r#   r"   r   r   psutilr  Zvirtual_memory
disk_usagepercentImportErrorr  r
   rC   ra   r   rQ   r   r!   )r$   rb   r  r%   r  r	  r   r   r  r  memoryZdiskr  r   Zcollection_statusr  r&   r&   r'   get_system_health_statusm  s|    

 







z%MongoHandler.get_system_health_statusc                 C   s,  z|  |sdddW S ddlm}m} | }|dkrJ||dd }nV|d	krb||dd
 }n>|dkrz||dd }n&|dkr||dd }n||dd }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r|d}|ddddi d+|
|< ||dd7 }q|D ]h}|d& }||
kr|d, |
| d,< |d- |
| d-< |d. D ]&}|d/ }|d0 }||
| d. |< qq|D ](}|d& }||
krN|d1 |
| d1< qN|	D ](}|d& }||
kr||d2 |
| d2< q|t|
	 }|j
d3d4 d5 d6|| | |t|d7W S  tk
r& } z&td8t|  dd9d W Y S d:}~X Y nX d:S );z&Get user activity summary (admin only)FrZ   r,   r   r	   rv   r[   r   rh  ri  rg  r  rk  rl  rm  r4   r{   r  $dateToString%Y-%m-%dr  r   dater  )r  r   r  	$addToSetr  )r0   r   r   z	$_id.date$count$sizez$users$push$_id.source_typer   r   )r0   r   unique_userssource_typesr  r0   r0   	new_usersr5   $last_loginr0   r}   )r  r   r  r  r}   r  r   r  r  r   r   r  r}   c                 S   s   | d S )Nr  r&   rw  r&   r&   r'   ry  6  rz  z8MongoHandler.get_user_activity_summary.<locals>.<lambda>r=  T)r-   r}  r~  r  activity_summaryZ
total_daysz%Error getting user activity summary: z#Failed to retrieve activity summaryN)rY   r
   r   rC   r_   r   r  r   strftimer  r   ra   r   r#   r   r!   r"   )r$   rb   r}  r
   r   r  r~  r  Zuser_registration_summaryZlogin_activity_summaryZcombined_summarycurrent_dateZdate_strsummaryZsource_type_infor   r   Zactivity_summary_listr%   r&   r&   r'   get_user_activity_summary  s    












	z&MongoHandler.get_user_activity_summaryc                 C   s  zb|  |sdddW S ddlm}m} | }|dkrJ||dd }nV|d	krb||dd
 }n>|dkrz||dd }n&|dkr||dd }n||dd }| ji }| jdd|ii}| jdd|ii}	t| jddd|ii}
|dkr|| d nd}|dkr|
| d nd}|dkr<||	 | d 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,W S  tk
r } z&td-t|  dd.d W Y S d}~X Y nX dS )/z(Get user engagement metrics (admin only)FrZ   r,   r   r	   rv   r[   r   rh  ri  rg  r  rk  rl  r5   r{   r4   rX   rW  rm  r  r  r  )r0   activity_countNrn  z$activity_countr  $min)r0   avg_activity_per_usermax_activitymin_activity)r  r  r  r  r  r  r   r   z$roler/  r  r  r  )r}  r~  r  r|   r}   r  users_with_activityengagement_rateactivity_rateretention_rateactivity_statssource_type_distributionrole_distributionT)r-   engagement_metricsz'Error getting user engagement metrics: z%Failed to retrieve engagement metrics)rY   r
   r   rC   r   r   r   r   distinctr_   r  ra   roundr#   r   r!   r"   )r$   rb   r}  r
   r   r  r~  r|   r}   r  r  r  r  r  Zuser_activity_frequencyr  r  r  r  r%   r&   r&   r'   get_user_engagement_metricsE  s    
  
 


	z(MongoHandler.get_user_engagement_metricsc                    s|  z.|  |sdddW S ddlm}m} | }|dkrJ||dd }nV|d	krb||dd
 }n>|dkrz||dd }n&|dkr||dd }n||dd }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rv|	d# d$kr6d%}
n@|	d# d&krJd'}
n,|	d# d(kr^d)}
n|	d# d*krrd+}
nd}
||	d, |
t|	d# d+|	d" d- q|rt	d.d/ |D t
| }i }tdd0D ]& t
 fd1d2|D |d3  < qnd}d4d5 tdd0D }g }|D ]}| jd6|d, iddddd7}|r||d, |d8 |d9 |d:d;|d< |d# |d" |dr|d  nd=d> q|jd?d@ dAdB || | t|d+|t
||t
dCd2 |D t
dDd2 |D t
dEd2 |D t
dFd2 |D t
dGd2 |D dHdI}dA|dJW S  tk
rv } z&tdKt|  ddLd W Y S d=}~X Y nX d=S )Mz2Get user feedback and ratings metrics (admin only)FrZ   r,   r   r	   rv   r[   r   rh  ri  rg  r  rk  rl  rm  r4   r{   r  r  r  rp  rq  rr  rs  )r0   r   successful_test_casesr  r  z	$multiply$dividez$successful_test_casesz$total_test_casesrW  )rX   r   ru  r   ru  r     r     F   r1  <   r/  rX   )rX   satisfaction_scoreru  r   c                 s   s   | ]}|d  V  qdS r  Nr&   r   ur&   r&   r'   r     s     z9MongoHandler.get_user_feedback_metrics.<locals>.<genexpr>   c                    s   g | ]}|d   kr|qS r  r&   r  r   r&   r'   
<listcomp>  s      z:MongoHandler.get_user_feedback_metrics.<locals>.<listcomp>score_c                 S   s   i | ]}d | dqS )r  r   r&   r   r   r&   r&   r'   r    	  s      z:MongoHandler.get_user_feedback_metrics.<locals>.<dictcomp>r0   r2   r*   r3   r4   r2   r*   r3   r)   r  N)rX   r2   r*   r3   r  ru  r   
user_sincec                 S   s   | d S Nr  r&   rw  r&   r&   r'   ry  	  rz  z8MongoHandler.get_user_feedback_metrics.<locals>.<lambda>Tr{  c                 S   s   g | ]}|d  dkr|qS ru  r  r&   r  r&   r&   r'   r  %	  s      c                 S   s,   g | ]$}d |d   kr dk rn q|qS r  ru  r  r&   r  r&   r&   r'   r  &	  s
        c                 S   s,   g | ]$}d |d   kr dk rn q|qS r  ru  r  r&   r  r&   r&   r'   r  '	  s
        c                 S   s,   g | ]$}d |d   kr dk rn q|qS r  ru  r  r&   r  r&   r&   r'   r  (	  s
        c                 S   s   g | ]}|d  dk r|qS ru  r  r&   r  r&   r&   r'   r  )	  s      )	excellentgoodaveragebelow_averageZpoor)r}  r~  r  overall_satisfactionsatisfaction_distributiontotal_users_analyzeduser_satisfaction_detailsZsuccess_rate_summary)r-   feedback_metricsz%Error getting user feedback metrics: z#Failed to retrieve feedback metrics)rY   r
   r   rC   r_   r   r  r   r  sumr   ranger   r;   rQ   ra   r   r#   r   r!   r"   )r$   rb   r}  r
   r   r  r~  Ztest_case_success_ratesZuser_satisfactionr  r  Zavg_satisfactionr  Z!activity_satisfaction_correlationr)   user_detailsr  r%   r&   r  r'   get_user_feedback_metrics  s    
 
&
z&MongoHandler.get_user_feedback_metricsrk  c                    s  z|  |sdddW S ddlm}m} | }|dkrN||dd }d	}nJ|d
krj||dd }d}n.|dkr||dd }d	}n||dd }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 d" d }|j
 d#| }n
|d	}|ddddddd$ |< |dkr||dd7 }n(|d
kr||dd7 }n||dd7 }qp|D ](}|d }| kr*|d%  | d%< q*|	D ]8}|d }| krX|d&  | d&< |d'  | d'< qX|
D ](}|d }| kr|d(  | d(< qt  }t|D ]\}}|dkrJ||d  } | d% } | d% }|dkr&|| | d) }n|dkr4d)nd}t|d* | d+< t fd,d-|d.|d  D }|dkr | d( | d) }nd}t|d* | d/< qt  }td0d- |D }td1d- |D rtd2d- |D td3d4 |D  nd}|r td5d- |D t| nd}|| | |t|d*t|d*||r\t|d6d7 d8nd.|rtt|d9d7 d8nd.t|d:d;}d<|d=W S  tk
r } z&td>t|  dd?d W Y S d.}~X Y nX d.S )@z#Get user growth trends (admin only)FrZ   r,   r   r	   rg  r  r   %Y-%mquarterr  z%Y-Q%qrk  rl  rm  r4   r{   r  r  r  r  r  r[   r  r  r0   r  r  r  )r0   total_activitiesr  r5   r  r  r1  z-Q)periodr  r  r  r}   growth_rater  r  r  r  r}   rW  r/  r  c                 3   s   | ]} | d  V  qdS r  Nr&   )r   pZcombined_trendsr&   r'   r   	  s     z6MongoHandler.get_user_growth_trends.<locals>.<genexpr>Nr  c                 s   s   | ]}|d  V  qdS r  r&   r   trendr&   r&   r'   r   	  s     c                 s   s   | ]}|d  dkV  qdS r  r   Nr&   r   tr&   r&   r'   r   	  s     c                 s   s"   | ]}|d  dkr|d  V  qdS r  r&   r  r&   r&   r'   r   	  s      c                 S   s   g | ]}|d  dkr|qS )r  r   r&   r  r&   r&   r'   r  	  s      z7MongoHandler.get_user_growth_trends.<locals>.<listcomp>c                 s   s   | ]}|d  V  qdS )r  Nr&   r  r&   r&   r'   r   	  s     c                 S   s   | d S )Nr  r&   rw  r&   r&   r'   ry  	  rz  z5MongoHandler.get_user_growth_trends.<locals>.<lambda>r  c                 S   s   | d S )Nr  r&   rw  r&   r&   r'   ry  	  rz  )Zbest_growth_periodZbest_activity_periodZtotal_periods)r}  r~  r  total_new_usersaverage_growth_rateZaverage_activity_ratetrendsr  T)r-   growth_trendsz"Error getting user growth trends: z Failed to retrieve growth trends)rY   r
   r   rC   r_   r   r  r   r  rg  rk  sortedr   	enumerater  r  r  r  r   ra   maxr#   r   r!   r"   )r$   rb   r}  r
   r   r  r~  date_formatZuser_registration_trendsZuser_activity_trendsZuser_login_trendsr  Z
period_keyr  r  periodsr   r  Zprev_periodZ
prev_usersZcurrent_usersr  Ztotal_users_in_periodr  Zgrowth_trends_listr  Zavg_growth_rateZavg_activity_rater  r%   r&   r  r'   get_user_growth_trends3	  s    



















"
<$z#MongoHandler.get_user_growth_trendsc           "      C   s  z|  |sdddW S ddlm}m} | }|dkrJ||dd }n>|d	krb||d
d }n&|dkrz||dd }n||d
d }g }|}||kr||dd }	t| jd||	diddd}
|
rt|
}dd |
D }ddddg}i }|D ]t}|	||d d }||dd }| j	d|i||dd}|dkrP|| d nd}|t
|dd|d| < q|| |	 ||d |	}qt|}|dkrtdd |D | }tdd |D | }tdd |D | }td d |D | }nd } } }}g }|D ]}||d! }||d" }	d|d# d$ d%  }||d& d'|	d& |d( |d# d) d% |d# d$ d% t
|dd* qt| jd+dd,|iiid-d.d/did0d1id2d1id3id4d5dd6d7d8d9gid:gid;ig}|r0td<d |D t| }td=d |D t| }nd }}|| | ||t
|dt
|dt
|dt
|dd>|t|t
|dt
|dd?d@} dA| dBW S  tk
r }! z&tdCt|!  ddDd W Y S dE}!~!X Y nX dES )Fz(Get user retention analysis (admin only)FrZ   r,   r   r	   rh  r  ri  rg  r  r   r     r[   r4   r{   z$lt)r0   r4   c                 S   s   g | ]}|d  qS )r0   r&   r   r)   r&   r&   r'   r  	  s     z<MongoHandler.get_user_retention_analysis.<locals>.<listcomp>r/  r1  z$inr   rW  )r}   r  Zweek_)cohort_start
cohort_endcohort_sizeretention_datac                 s   s   | ]}|d  d d V  qdS )r  week_1r  Nr&   r   cohortr&   r&   r'   r   
  s     z;MongoHandler.get_user_retention_analysis.<locals>.<genexpr>c                 s   s   | ]}|d  d d V  qdS )r  Zweek_2r  Nr&   r   r&   r&   r'   r   
  s     c                 s   s   | ]}|d  d d V  qdS )r  Zweek_3r  Nr&   r   r&   r&   r'   r   
  s     c                 s   s   | ]}|d  d d V  qdS )r  week_4r  Nr&   r   r&   r&   r'   r   
  s     r  r  r  r  r  r  z to r  r  )Zcohort_periodr  week_1_retentionweek_4_retention
churn_raterm  r{   r  r  r  r  r  r  )r0   r   first_activityr  r  r  r  	$subtract$last_activity$first_activity \&)rX   r   lifetime_daysc                 s   s   | ]}|d  V  qdS )r  Nr&   r  r&   r&   r'   r   K
  s     c                 s   s   | ]}|d  V  qdS r   Nr&   r  r&   r&   r'   r   L
  s     )r  Zweek_2_retentionZweek_3_retentionr  )r  Zaverage_lifetime_daysZaverage_test_cases_per_user)r}  r~  r  total_cohortscohort_analysisoverall_retention_metricschurn_analysisuser_lifetime_analysisT)r-   retention_analysisz'Error getting user retention analysis: z%Failed to retrieve retention analysisN)rY   r
   r   rC   r_   r   r`   r   r   r   r  r   ra   r  rP  r  r  r#   r   r!   r"   )"r$   rb   r}  r
   r   r  r~  r  Zcurrent_cohort_startr  Zcohort_usersr  Zcohort_user_idsZretention_periodsr  r  Zperiod_startZ
period_endr}   r  r  Zavg_week_1_retentionZavg_week_2_retentionZavg_week_3_retentionZavg_week_4_retentionr  r  r  r  r  Zavg_lifetime_daysZavg_test_cases_per_userr  r%   r&   r&   r'   get_user_retention_analysis	  s    


	
z(MongoHandler.get_user_retention_analysisc                 C   sd  z|  |sdddW S ddlm}m} | }|dkrJ||dd }nV|d	krb||dd
 }n>|dkrz||dd }n&|dkr||dd }n||dd }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r0d7}n$|d8kr@d9}n|dkrPd:}nd;}|	t
|d3 |d< |d= |d>d?|d# |d@ t|d5 dA|dB q|jdCdD dEdF g }|D ]}|d }|dG }dH}dI|  krdJk rn ndK}nHdJ|  kr
dLk rn ndM}n&dL|  kr,dNk r6n ndO}ndP}|	||||dQdRdS qg }dTdUdVdWdXdYdZg}|D ]0}|d }|dG }|	|||d  |d[ qt|| | |||	|
||rt|d\dD d]nd^|rt|d_dD d]nd^t|td`da |D dbdc	}dE|ddW S  tk
r^ } z&tdet
|  ddfd W Y S d^}~X Y nX d^S )gz'Get user behavior patterns (admin only)FrZ   r,   r   r	   rv   r[   r   rh  ri  rg  r  rk  rl  rm  r4   r{   r  z$hourr  r  r  r  r0   z
$dayOfWeekr  r  )rX   r   z$_id.user_idr  r  r  r  )r0   r  r  r  r   r  r  r  )r  time)r0   r`  r  r  r  r  z	$setUnionz$sessions.dater  z$total_activitiesz	$sessions)rX   r  unique_daysavg_activities_per_dayZsession_patternsrX   rv  r  r  	Very Highr1  HighMediumLowr2   r*   r3   r)   r  r/  )rX   r2   r*   r3   r  r  r  engagement_scorec                 S   s   ddddd| d  S )Nr  r1  r/  r[   )r  r  r  r  r  r&   rw  r&   r&   r'   ry  
  s    z9MongoHandler.get_user_behavior_patterns.<locals>.<lambda>Tr{  r    r     ZMorning   Z	Afternoon   ZEveningZNight02dz:00)rw   r}  r  Zformatted_timeSundayMondayTuesday	WednesdayThursdayFridaySaturday)
day_numberday_namer  c                 S   s   | d S Nr  r&   rw  r&   r&   r'   ry    rz  r  Nc                 S   s   | d S r*  r&   rw  r&   r&   r'   ry    rz  c                 S   s   g | ]}|d  dkr|qS )r  )r  r  r&   r  r&   r&   r'   r    s      z;MongoHandler.get_user_behavior_patterns.<locals>.<listcomp>)Z	peak_hourZpeak_dayr  Zhigh_engagement_users)	r}  r~  r  hourly_activityweekly_patternssource_type_preferencesuser_session_patternsengagement_patternsr  )r-   behavior_patternsz&Error getting user behavior patterns: z$Failed to retrieve behavior patterns)rY   r
   r   rC   r_   r   r  r   r;   r   r"   rQ   r  r   ra   r  r   r#   r   r!   )r$   rb   r}  r
   r   r  r~  r+  daily_activityr-  r.  r/  user_patternr  Zactivity_frequencyr  Zpeak_usage_timesZ	hour_datarw   r   r,  Z	day_namesZday_datar(  r0  r%   r&   r&   r'   get_user_behavior_patternsj
  s    

	













z'MongoHandler.get_user_behavior_patternsc                 C   s  z|  |sdddW S ddlm}m} | }|dkrJ||dd }nV|d	krb||dd
 }n>|dkrz||dd }n&|dkr||dd }n||dd }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rD||
d  j
}| |	d# |	d$ |t|	d% }|t|	d! |
d& |
d' |
	d(d)||	d# t|	d% |	d% ||	d$ rt|	d$ d*ndd+
 qi }|D ].}|d, }||krg ||< || | qi }| D ]\}}t|}|dkr:td-d. |D | nd}|dkr^td/d. |D | nd}|dkrtd0d. |D | nd}||rt|t| d1 d*ndt|d*t|d*t|d*|d2||< q
i }| D ]\}}|d3 ri }|d3 D ]*}|d% D ]}|	|dd ||< qqt| d4d5 d6d7}|d8d9 | |d: | |d; d<||< qi }| D ]\}}g }|d=kr|d>d?d@g nn|dAkr|dBdCdDg nR|dEkr|dFdGdHg n6|dIkr|dJdKdLg n|dMkr|dNdOdPg |||< qv|| | t||||||rRt| dQd5 dRd nd8|rrt| dSd5 dRd nd8t|dTdU	}d6|dVW S  tk
r } z&tdWt|  ddXd W Y S d8}~X Y nX d8S )Yz+Get user segmentation analysis (admin only)FrZ   r,   r   r	   rv   r[   r   rh  ri  rg  r  rk  rl  rm  r4   r{   r  r  r  r  r  r  r  r  rn  r  r  r  r	  r
  )r0   r   r  r  r  avg_daily_activityr0   r  r   r4  r  r2   r*   r3   r)   r/  )
rX   r2   r*   r3   segmentr   source_types_usedr  user_age_daysr4  r5  c                 s   s   | ]}|d  V  qdS r  r&   r  r&   r&   r'   r     s     z>MongoHandler.get_user_segmentation_analysis.<locals>.<genexpr>c                 s   s   | ]}|d  V  qdS )r7  Nr&   r  r&   r&   r'   r     s     c                 s   s   | ]}|d  V  qdS )r6  Nr&   r  r&   r&   r'   r     s     rW  )r|   
percentageavg_test_casesavg_age_daysavg_source_typesr   r   c                 S   s   | d S Nr[   r&   rw  r&   r&   r'   ry    rz  z=MongoHandler.get_user_segmentation_analysis.<locals>.<lambda>Tr{  Nr1  r9  r;  )Zpreferred_source_typesactivity_levelZengagement_levelPower Usersz3Provide advanced features and customization optionsz7Offer priority support and early access to new featuresz#Consider beta testing opportunitiesActive Usersz0Encourage exploration of additional source typesz0Provide tips for optimizing test case generationz+Offer training materials and best practicesRegular Usersz7Increase engagement through notifications and remindersz'Provide onboarding and tutorial contentz%Offer incentives for consistent usageOccasional UserszImprove onboarding experiencezProvide quick-start templateszSend re-engagement campaigns	New Usersz Provide comprehensive onboardingz Offer guided tours and tutorialszSet up welcome series emailsc                 S   s   | d d S )Nr[   r|   r&   rw  r&   r&   r'   ry    rz  r  c                 S   s   | d d S )Nr[   r9  r&   rw  r&   r&   r'   ry    rz  )Zlargest_segmentZmost_active_segmentZtotal_segments)	r}  r~  r  r  segment_groupssegment_statisticssegment_behaviorsegment_recommendationsr  )r-   segmentation_analysisz*Error getting user segmentation analysis: z(Failed to retrieve segmentation analysis)rY   r
   r   rC   r_   r   r  r   r;   rQ   r   _determine_user_segmentr   r   r"   r  r   r  r  _get_activity_level_description!_get_engagement_level_descriptionr   ra   r  r#   r   r!   )r$   rb   r}  r
   r   r  r~  Zuser_activity_dataZuser_segmentsr  r  r7  r5  rC  r)   rD  r   r|   r9  r:  r;  rE  r   Zsource_type_countsr   Zsorted_source_typesrF  r  rG  r%   r&   r&   r'   get_user_segmentation_analysis&  s   







$$$







  z+MongoHandler.get_user_segmentation_analysisc                 C   sH   |dkrdS |dkr |dkr dS |dkr4|dkr4dS |d	kr@d
S dS dS )z'Helper method to determine user segment   rB  r   r1  r>  r   r[   r?  r  r@  rA  Nr&   )r$   r   r4  r7  Zsource_types_countr&   r&   r'   rH    s    z$MongoHandler._determine_user_segmentc                 C   s,   |dkrdS |dkrdS |dkr$dS dS dS )	z/Helper method to get activity level descriptionr  r  r1  r  r[   r  r  Nr&   )r$   r9  r&   r&   r'   rI    s    z,MongoHandler._get_activity_level_descriptionc                 C   s,   |dkrdS |dkrdS |dkr$dS dS dS )	z1Helper method to get engagement level descriptionr1  r  r/  r  r[   r  r  Nr&   )r$   r;  r&   r&   r'   rJ    s    z.MongoHandler._get_engagement_level_descriptionc                 C   s
  z|  |sdddW S ddlm}m} | }|dkrJ||dd }nV|d	krb||dd
 }n>|dkrz||dd }n&|dkr||dd }n||dd }dddddddg}i }| jdd|ii}	|	ddd|d< | jd|idddd}
|
|	dkrt|
|	 d dnd|	dkr6t|	|
 |	 d dndd|d< t| j	ddd|ii}||	dkrzt||	 d dnd|
dkrt|
| |
 d 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||	 d dnd|dkr$t|| | d 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rt||	 d dnd|dkrt|| | d 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||	 d dnd|dkr<t|| | d 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rt||	 d dnd|dkrt|| | d dndd|d< |	dkrt||	 d dnd}td.d/ | D t| }g }t| d0d1 dd2dd3 }|D ]@\}}|d4 dkr4|d5|d6d7  d8|d4  d9 q4t| d:d1 dd2dd3 }|D ]@\}}|d; dkr|d<|d6d7  d=|d;  d> qt| j
d dd|iiid!d"d?d'd@dAid#didBidCdDdEiidFdGig}g }|D ]L}t|dH dId1 dJ}dKdL |D }|t|dM ||dD t|dN q,|| | |||	|t|d|dO||dPdQdRdSdTgdU	}d|dVW S  tk
r } z&tdWt|  ddXd W Y S d}~X Y nX dS )Yz0Get user conversion funnel analysis (admin only)FrZ   r,   r   r	   rv   r[   r   rh  ri  rg  r  rk  rl  
registeredZfirst_loginfirst_test_caseZmultiple_test_casesZmultiple_source_typesZregular_userZ
power_userr4   r{   rW  )r   r8  dropoffTN$exists$ner4   r5   r/  rX   rm  r  r  r  )r0   r  r  r  r  )r0   r  z$exprr  z$source_typesr  r   c                 s   s   | ]}|d  V  qdS )r8  Nr&   )r   stager&   r&   r'   r     s     z:MongoHandler.get_user_conversion_funnel.<locals>.<genexpr>c                 S   s   | d d S )Nr[   rO  r&   rw  r&   r&   r'   ry    rz  z9MongoHandler.get_user_conversion_funnel.<locals>.<lambda>r{  r1  rO  zBiggest dropoff at _ z stage: %c                 S   s   | d d S )Nr[   r8  r&   rw  r&   r&   r'   ry    rz  r8  zBest performing stage: z with z% conversionr  r  )r   r  )r0   journeyr  r  r  r   z$limitr   rX  c                 S   s   | d S Nr  r&   rw  r&   r&   r'   ry    rz  r  c                 S   s   g | ]}|d  qS )r   r&   )r   stepr&   r&   r'   r    s     z;MongoHandler.get_user_conversion_funnel.<locals>.<listcomp>r0   )rX   journey_pathr  Zjourney_length)total_registeredoverall_conversion_rateZaverage_stage_conversionZfinal_stage_usersz9Focus 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_dataZoverall_metricsfunnel_insightsuser_journeysr  )r-   conversion_funnelz&Error getting user conversion funnel: z$Failed to retrieve conversion funnel)rY   r
   r   rC   r   r   r  r   r   r  r  r  r  r  r   r   r   r   r_   r"   ra   r#   r   r!   )r$   rb   r}  r
   r   r  r~  r^  r_  r\  Zfirst_login_usersZusers_with_test_casesZusers_with_multiple_test_casesZusers_with_multiple_sourcesr   Zpower_usersr]  Zavg_stage_conversionr`  Zbiggest_dropoffsrT  r   Zbest_stagesZuser_journey_datara  rX  Zsorted_journeyr[  rb  r%   r&   r&   r'   get_user_conversion_funnel   s2   
 
"

 "
	"
	"
	"
	"
 ,,


z'MongoHandler.get_user_conversion_funnelc           &         s  zp|  |sdddW S ddlm}m} | }|dkrJ||dd }nV|d	krb||dd
 }n>|dkrz||dd }n&|dkr||dd }n||dd }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" |
 d# nd}d}t|d$ d%d& }t|
d' d%d( }tt|	d) d* d%d+ }d}|		d,r|	d, }|d-krd.}n4|d/krd&}n$|d0krd1}n|d2krd+}nd3}|| | | }|d4krd5}n4|d6krd7}n$|d8kr"d9}n|d:kr2d;}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 q|rtdEdF |D t| }tdGdH |D tdIdH |D tdJdH |D tdKdH |D tdLdH |D dM}tdNdH |D tdOdH |D tdPdH |D tdQdH |D tdRdH |D dS}nd}i }i }g }t|dTdU dVdWdCd% }|r|dXttdYdF |D t| d*  dZdH |D }|rDtd[dF |D t| }|d\t|d* d] t|dkrbd^dH |D d_dH |D  t|}t fd`dFt|D }t}t }tdadF D }tdbdF  D } || ||  || ||  ||  ||   d.  }!t|!dckr"|ddt|!d* de n@t|!d.krJ|dft|!d* de n|dgt|!d* de g }"|	d;d|	d<d dkr|"dhdidjg |	dkddkr|"dldmdng t|dkrtdodF |D tdpdH |D  }#|#d0kr|"dq || | t|t|d*|||||"|d6kr0drndsdtt krFt|nddut kr\t|nddvdw}$dV|$dxW S  tk
r }% z&tdyt|%  ddzd W Y S dC}%~%X Y nX dCS ){z8Get user satisfaction and feedback analysis (admin only)FrZ   r,   r   r	   rv   r[   r   rh  ri  rg  r  rk  rl  rm  r4   r{   r  r  r  rp  rq  rr  rs  failedr  r  rn  ro  r  r  )r0   r   r  Zfailed_test_casesr  rt  r  r   r  rW  r   r  皙?r   333333?r  r/  皙?rt  r        ?i,  iX  g433333?i  皙?g      @Very Satisfiedg      @	Satisfiedg      @Neutralg      ?DissatisfiedVery Dissatisfiedr0   r  r2   r*   r3   r)   N)rX   r2   r*   r3   r  satisfaction_levelru  r   r6  rt  r  c                 s   s   | ]}|d  V  qdS r  r&   r  r&   r&   r'   r   B  s     zBMongoHandler.get_user_satisfaction_and_feedback.<locals>.<genexpr>c                 S   s   g | ]}|d  dkr|qS )ro  rj  r&   r  r&   r&   r'   r  F  s      zCMongoHandler.get_user_satisfaction_and_feedback.<locals>.<listcomp>c                 S   s   g | ]}|d  dkr|qS )ro  rk  r&   r  r&   r&   r'   r  G  s      c                 S   s   g | ]}|d  dkr|qS )ro  rl  r&   r  r&   r&   r'   r  H  s      c                 S   s   g | ]}|d  dkr|qS )ro  rm  r&   r  r&   r&   r'   r  I  s      c                 S   s   g | ]}|d  dkr|qS )ro  rn  r&   r  r&   r&   r'   r  J  s      )rj  rk  rl  rm  rn  c                 S   s   g | ]}|d  dkr|qS r  r&   r  r&   r&   r'   r  O  s      c                 S   s,   g | ]$}d |d   kr dk rn q|qS r  r&   r  r&   r&   r'   r  P  s
        c                 S   s,   g | ]$}d |d   kr dk rn q|qS r  r&   r  r&   r&   r'   r  Q  s
        c                 S   s,   g | ]$}d |d   kr dk rn q|qS r  r&   r  r&   r&   r'   r  R  s
        c                 S   s   g | ]}|d  dk r|qS r  r&   r  r&   r&   r'   r  S  s      )zExcellent (90-100%)zGood (80-89%)zAverage (70-79%)zBelow Average (60-69%)Poor (<60%)c                 S   s   | d S r  r&   rw  r&   r&   r'   ry  ^  rz  zAMongoHandler.get_user_satisfaction_and_feedback.<locals>.<lambda>Tr{  z5Top performers have an average satisfaction score of c                 s   s   | ]}|d  V  qdS r  r&   r  r&   r&   r'   r   `  s     c                 S   s   g | ]}|d  dkr|qS )ro  )rm  rn  r&   r  r&   r&   r'   r  c  s      c                 s   s   | ]}|d  V  qdS )ru  Nr&   r  r&   r&   r'   r   e  s     z7Low satisfaction users have an average success rate of rW  c                 S   s   g | ]}|d  qS )ru  r&   r  r&   r&   r'   r  j  s     c                 S   s   g | ]}|d  qS r  r&   r  r&   r&   r'   r  k  s     c                 3   s   | ]}|  |  V  qd S Nr&   r  Zsatisfaction_scoresZsuccess_scoresr&   r'   r   o  s     c                 s   s   | ]}|| V  qd S rq  r&   )r   rx  r&   r&   r'   r   r  s     c                 s   s   | ]}|| V  qd S rq  r&   )r   yr&   r&   r'   r   s  s     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 systemrp  z(Investigate causes of high failure ratesz(Improve error handling and user guidancez&Consider simplifying complex workflowsc                 s   s"   | ]}|d  dkr|d  V  qdS )rt  r   Nr&   r  r&   r&   r'   r     s      c                 S   s   g | ]}|d  dkr|qS )rt  r   r&   r  r&   r&   r'   r    s      z?Optimize test case generation process to reduce completion timeZ	ImprovingzNeeds Attentiontop_performerslow_satisfaction_users)Zsatisfaction_trendZtop_performers_countZimprovement_needed_count)r}  r~  r  r  r  r  success_rate_distributionr  feedback_insightsimprovement_recommendationsr  )r-   satisfaction_analysisz.Error getting user satisfaction and feedback: z(Failed to retrieve satisfaction analysis)rY   r
   r   rC   r_   r   r  minr   rQ   r   r;   r   r"   r  ra   r  r  r  absr   localsr#   r   r!   )&r$   rb   r}  r
   r   r  r~  r  Zsatisfaction_datar  Ztotal_casesru  r  Zsuccess_scoreZactivity_scoreZdiversity_scoreZcompletion_scoreZavg_timero  r  r  r  rw  rx  ru  rv  avg_success_ratenZsum_xysum_xZsum_yZsum_x2Zsum_y2Zcorrelationry  rt  rz  r%   r&   rr  r'   "get_user_satisfaction_and_feedback  s8   
  












,4$

z/MongoHandler.get_user_satisfaction_and_feedbackc           #      C   s  z|  |sdddW S ddlm}m} | }|dkrJ||dd }nV|d	krb||dd
 }n>|dkrz||dd }n&|dkr||dd }n||dd }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 ]>}|d  }| jd |idddddd!}|r|d }|d" }|d# }|r|r|| j	}|dkrz|| }n|}nd}|r|| j	nd}| 
||||d$ }| |}t||d% |d& |d'd(|||d) |d* |d+ d,	}|| |d) d-kr|	| n2|d* d.kr,|
| n|d+ d/kr|| q|rtd0d1 |D t| }td2d1 |D t| }td3d1 |D t| }td4d5 |D }td6d5 |D }td7d5 |D }nd } }}d } }}g }|d8kr|d9t|d: d d; |d-kr<|d<t|d: d d= |d>k rb|d?t|d: d d@ |dkr||| dA |dkr|| dB g }|	r|dCdDdEg |
r|dFdGdHg |r|dIdJdKg | ||} || | t|t|dLt|dLt|dL|||dM||	|
|dN||| |d8kr>dOn|dPkrLdQndR|d-kr\dOn|d>krjdQndR|d8krzdSn|d/krdTndUdVdW}!dX|!dYW S  tk
r }" z&tdZt|"  dd[d W Y S d\}"~"X Y nX d\S )]z*Get user predictive analytics (admin only)FrZ   r,   r   r	   rv   r[   r   rh  ri  rg  r  rk  rl  rm  r4   r{   r  r  r  r  r  rr  )r  r   r]   r  r  r  )r0   
activitiesr  r  r  r  r  r   r0   )r2   r*   r3   r4   r5   r  r  r  r2   r*   r3   r)   
churn_riskgrowth_potentialr  )	rX   r2   r*   r3   predictionsuser_category
risk_scorer  r  rt  皙?re  c                 s   s   | ]}|d  V  qdS )r  Nr&   r  r&   r&   r'   r     s     z=MongoHandler.get_user_predictive_analytics.<locals>.<genexpr>c                 s   s   | ]}|d  V  qdS )r  Nr&   r  r&   r&   r'   r     s     c                 s   s   | ]}|d  V  qdS )r  Nr&   r  r&   r&   r'   r      s     c                 S   s   g | ]}|d  dkr|qS )r  rt  r&   r  r&   r&   r'   r  #  s      z>MongoHandler.get_user_predictive_analytics.<locals>.<listcomp>c                 S   s   g | ]}|d  dkr|qS )r  r  r&   r  r&   r&   r'   r  $  s      c                 S   s   g | ]}|d  dkr|qS )r  re  r&   r  r&   r&   r'   r  %  s      333333?zHigh overall churn risk (rW  z#%) - implement retention strategieszStrong growth potential (z%%) - focus on expansion opportunitiesrh  zLow engagement levels (z#%) - implement engagement campaignsz8 users at high churn risk - prioritize retention effortsz6 users with high growth potential - focus on expansionz:Implement targeted retention campaigns for high-risk usersz+Provide personalized support and incentivesz.Analyze common patterns among churn-risk userszCOffer advanced features and premium options to high-potential usersz1Provide upselling and cross-selling opportunitiesz'Create loyalty programs for power usersz4Send re-engagement campaigns to low-engagement usersz-Provide onboarding improvements and tutorialszImplement gamification elementsr1  )Zaverage_churn_riskZaverage_growth_potentialZaverage_engagement_scorehigh_risk_usershigh_potential_userslow_engagement_users)churn_risk_usersgrowth_potential_usersengagement_opportunitiesr  rf  r  r  GoodFairPoor)overall_risk_levelZgrowth_opportunityZengagement_status)r}  r~  r  r  Zpredictive_metricsuser_predictionsZuser_categoriespredictive_insightsaction_recommendationspredictive_trendsr  T)r-   predictive_analyticsz)Error getting user predictive analytics: z'Failed to retrieve predictive analyticsN)rY   r
   r   rC   r_   r   r  r   r;   r   _predict_user_behavior_categorize_user_for_predictionr"   rQ   r   r  r   r  r   _calculate_predictive_trendsra   r#   r   r!   )#r$   rb   r}  r
   r   r  r~  Zuser_activity_patternsr  r  r  r  r2  rX   r  r  r  r  Zactivity_perioddaily_activity_ratedays_since_last_activityr  r  Zuser_predictionZavg_churn_riskZavg_growth_potentialZavg_engagement_scorer  r  r  r  r  r  r  r%   r&   r&   r'   get_user_predictive_analytics  s$   













z*MongoHandler.get_user_predictive_analyticsc                 C   s  d}|dkr|d7 }n4|dkr(|d7 }n"|dkr:|d7 }n|dkrJ|d	7 }|d	k r\|d7 }n"|d
k rn|d7 }n|dk r~|d	7 }|dk r|d7 }n|dk r|d	7 }t |dkr$dd |D }|  g }tdt |D ]$}|| ||d   j}	||	 q|r$t|t | }
|
dkr$|d	7 }d}|dkr<|d7 }n:|dkrP|d7 }n&|d
krd|d7 }n|d	krv|d	7 }|dkr|d7 }n&|dkr|d7 }n|dkr|d	7 }tdd |D }t |dkr|d7 }nt |dkr|d	7 }|dkr|d	7 }d}|dkr|d7 }n:|d
kr.|d7 }n&|dkrB|d7 }n|d	krT|d	7 }|dkrh|d7 }n&|dkr||d7 }n|dkr|d	7 }|dkr|d7 }n|dkr|d	7 }t |dkr|d	7 }t|dt|dt|ddS )z&Helper method to predict user behaviorr   r  re     rf  rL  rg  r1  ri  rh        ?r  r   r[   c                 S   s   g | ]}|d  qS )r  r&   r   ar&   r&   r'   r    s     z7MongoHandler._predict_user_behavior.<locals>.<listcomp>r/  r   c                 s   s   | ]}|d  V  qdS r   Nr&   r  r&   r&   r'   r     s     z6MongoHandler._predict_user_behavior.<locals>.<genexpr>)r  r  r  )r   r   r  r   r   r  setr{  )r$   r  r  r  r  r  
timestampsZgapsr   gapZavg_gapr  r  r  r&   r&   r'   r  z  s    



































z#MongoHandler._predict_user_behaviorc                 C   sd   |d }|d }|d }|dkr$dS |dkr0dS |dkr<d	S |dkrP|d
krPdS |dkr\dS dS dS )z6Helper method to categorize users based on predictionsr  r  r  rt  zHigh Churn Riskr  zHigh Growth Potentialrf  zLow Engagementr  z
Power Userrh  zEngaged UserzStandard UserNr&   )r$   r  r  r  r  r&   r&   r'   r    s    z,MongoHandler._categorize_user_for_predictionc                 C   s   |si S i }|D ],}|d }||kr,d||< ||  d7  < qt |}i }| D ]\}}t|| d d||< qRg }	t| dd dd	D ]&\}}
|
d
kr|	| d|
 d q|||	t |dS )z,Helper method to calculate predictive trendsr  r   r[   rW  r/  c                 S   s   | d S r<  r&   rw  r&   r&   r'   ry    rz  z;MongoHandler._calculate_predictive_trends.<locals>.<lambda>Tr{  r   rn   z
% of users)Zcategory_distributioncategory_percentagesdominant_trendsZtotal_categories)r   r   r  r  r   )r$   r  r}  Zcategory_countsr)   categoryr|   r  r   r  r8  r&   r&   r'   r    s*    z)MongoHandler._calculate_predictive_trendsc                 C   s,  z|  |sdddW S ddlm}m} | }|dkrJ||dd }nn|d	krb||d
d }nV|dkrz||dd }n>|dkr||dd }n&|dkr||dd }n||dd }i }| |}|d r|d |d< | ||}	|	d r|	d |d< | ||}
|
d r|
d |d< | j||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 rJ|d |d< | |}|d rj|d  |d!< | ||}| |}| |}| |}|| | |||||t|| || t|t|d"d#	}d$|d%W S  tk
r& } z&td&t|  dd'd W Y S d(}~X Y nX d(S ))zCGet comprehensive user analytics combining all metrics (admin only)FrZ   r,   r   r	   rv   r[   r   rh  rL  rg  r  r  r  rk  rl  r-   r   r   r  r  )r}  performance_metricsr0  rG  rb  r  r  rz  r  r   r  r   )Ztotal_metrics_analyzedZdata_completenessZanalysis_timestampZrecommendations_countZinsights_count)	r}  r~  r  overall_health_scoreexecutive_summarykey_insightsstrategic_recommendationsanalytics_datar  T)r-   comprehensive_analyticsz,Error getting comprehensive user analytics: z*Failed to retrieve comprehensive analyticsN)rY   r
   r   rC   r   r  r  r  r3  rK  rc  r  r  r  r  r   r  _generate_executive_summary_generate_key_insights#_generate_strategic_recommendations_calculate_overall_health_scorera   r   _calculate_data_completenessr#   r   r!   r"   )r$   rb   r}  r
   r   r  r~  r  r   r  r  r  r0  rG  rb  r  r  rz  r  r   r   r  r  r  r  r  r%   r&   r&   r'    get_comprehensive_user_analytics  s    

















z-MongoHandler.get_comprehensive_user_analyticsc           
   	   C   sX  d| dg i g g g d}d|krh|d }|d  d|dd d	|d
d d|dd g d|kr|d }|dd|d|d|d< d|kr|d }|d  d|dd d|dd dg d|kr|d }|di dd}|d d|  d|krT|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)Z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}  )r  r}  r  r  r  zTotal new users: r  zAverage growth rate: r  rW  r  r  r  rM  r  zOverall churn risk level: r  r  zEngagement rate: r  zActivity rate: r  )r   rQ   r   )
r$   r  r}  r  r   perfr  predZ
risk_level
engagementr&   r&   r'   r    sH    






z(MongoHandler._generate_executive_summaryc                 C   s   g }d|kr:|d }| dddkr:|d|d  d d|krd|d }| dddk rd|d	 d
|kr|d
 }| di  dddk r|d d|kr|d }| drtdd |d D t|d  }|dt|d  |S )z)Generate key insights from analytics datar  r  r   zUser growth is positive with z
 new usersr  r  r   zGUser engagement is below optimal levels - consider engagement campaignsr  r  r  r  z<First-week retention needs improvement - focus on onboardingr  r  c                 s   s   | ]}|d  V  qdS r  r&   r  r&   r&   r'   r     s     z6MongoHandler._generate_key_insights.<locals>.<genexpr>Average test cases per user: r[   )rQ   r   r  r   r  )r$   r  insightsr  r  	retentionr  r9  r&   r&   r'   r    s&    


"z#MongoHandler._generate_key_insightsc           	      C   s  g }d|kr.|d }| dddk r.|d d|kr`|d }| di  ddd	k r`|d
 d|kr|d }| dddk r|d d|kr|d }| drdd |d D }t|t|d d kr|d d|kr|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  r  z;Develop long-term retention strategies and loyalty programsr  r  r  zCImplement user engagement campaigns and feature adoption strategiesr  r  c                 S   s   g | ]}|d  dk r|qS )r   r  r&   r  r&   r&   r'   r    s      zDMongoHandler._generate_strategic_recommendations.<locals>.<listcomp>rf  z@Provide additional support and training for low-performing usersr   r   r   z7Address system health issues to improve user experience)rQ   r   r   )	r$   r  r  r  r  r  r  low_performershealthr&   r&   r'   r    s0    






z0MongoHandler._generate_strategic_recommendationsc                 C   s^  d}d}d|krB|d }t |ddd d}||d 7 }|d7 }d|kr||d }t |ddd	 d}||d 7 }|d7 }d
|kr|d
 }t |di ddd	 d}	||	d 7 }|d7 }d|kr|d }
|
ddkrdnd}||d 7 }|d7 }|dkr|| }nd}t|d	 d}|dkr.d}n$|dkr>d}n|dkrNd}nd}|||dS )z9Calculate overall system health score from analytics datar   r  r  r   r  g      ?r  r  rW  r  r  r  r   r   r   rh  r[   r  	Excellentr  r  (   r  r  )scorer  Zfactors_analyzed)r{  rQ   r  )r$   r  Zhealth_scoreZtotal_factorsr  Zgrowth_scorer  r  r  Zretention_scorer  Zsystem_scoreZfinal_scoreZhealth_percentageZhealth_categoryr&   r&   r'   r    sJ    




z,MongoHandler._calculate_overall_health_scorec                 C   sZ   d}t |}t|| d d}|dkr,d}n |dkr:d}n|dkrHd	}nd
}||||dS )z&Calculate data completeness percentage   rW  r[   r  r  K   r  r  r  r  )r8  r,  available_metricstotal_possible_metrics)r   r  )r$   r  r  r  Zcompleteness_percentageZcompleteness_levelr&   r&   r'   r  Q  s    z)MongoHandler._calculate_data_completenessc                 C   s.  z| j ddi}|r"dddW S tt | t|dt	 |dt
 dddddddddddddd	d
	}| j |}|jrtd|  | jddt|jd| dd ddt|j||dddW S dddW S W nF tk
r( } z&tdt|  ddd W Y S d}~X Y nX dS )zGCreate the initial admin user (should only be called once during setup)r3   rJ   Fz7Admin user already exists. Cannot create another admin.r,   r/   NTrR  )	r0   r*   r1   r2   r3   r4   r5   r6   rS  z)Initial admin user created successfully: ZSYSTEM_SETUPZinitial_admin_createdzInitial admin user z created during system setup)rb   rX  r[  r\  z'Initial admin user created successfullyr8   )r-   r.   Z
admin_userrK   z#Error creating initial admin user: )r   r;   r"   rA   rB   r<   r=   r?   r@   r>   r
   rC   rD   r   r   r   r_  r#   r!   )r$   r*   r1   r2   rL   Zadmin_user_docrM   r%   r&   r&   r'   create_initial_admin_userh  s\    

z&MongoHandler.create_initial_admin_userc              
   C   s  zl| j d|i}|s$dddW S t| jd|idddddddd	d
}|D ]4}d|krtt|d |d< d|krX|d  |d< qX|	dd}| 
|}t|}td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rd| |}||
d< d|
dW S  tk
r } z&tdt|  ddd W Y S d}~X Y nX dS )r   r0   Frq   r,   rX   r[   r   r4   r   r   r3   r)   c                 S   s,   g | ]$}| d dt dr|qS )r4   r  r  )rQ   
startswithr
   rC   r  r   tcr&   r&   r'   r    s      z8MongoHandler.get_user_dashboard_data.<locals>.<listcomp>Nr   r2   r*   r5   r   r   r-   rS  )r   r   r   rS  r3   rJ   
admin_dataTr   r   r   )r   r;   r_   r   r`   r   r   r"   ra   rQ   rU  r   _get_admin_dashboard_datar#   r   r!   )r$   rX   r)   r   r   r3   rS  r   Zthis_month_test_casesr   r   r  r%   r&   r&   r'   r     s^     

	

c              
   C   s   z|  |}| |}| |d}| |}|d r@|di ni |d rV|di ni |d rl|dg ng |d r|di ni ddd	d
dgd}|W S  tk
r } z tdt|  i  W Y S d}~X Y nX dS )z!Get admin-specific dashboard datarh  r-   r   r   r  r  zView all userszSystem health checkzUser analyticszBackup datazExport reports)r   r   r   r   Zquick_actionsz$Error getting admin dashboard data: N)	r   r   r  r  rQ   r#   r   r!   r"   )r$   rb   r   r   r   r   r  r%   r&   r&   r'   r    s(    


z&MongoHandler._get_admin_dashboard_datac                 C   s  z4ddl m }m} | }|dkr4||dd }nn|dkrL||dd }nV|dkrd||d	d }n>|d
kr|||dd }n&|dkr||dd }n||d	d }t| j|d|iddddddddd}| jd|iddd}g }	|r|	dr|	
d|d dddd |D ]P}
|	
d|
d d|
	dd ddt|
d |
	dd|
	d d!d"d# q|r|	d$r|	
d%|d$ d&d'dd |	jd(d) d*d+ |	D ]}|d,  |d,< qi }|	D ]6}|d, d-d. }||krg ||< || 
| qt|	}td/d0 |	D }td1d0 |	D }t|	dkrt|	d2d) d3}t|	d4d) d3}||d, }||d, }|| j}|dkr|| }n|}n|}|||t|d5|rt| d6d) d3d nd-| |	d7}|| | ||	||||krdnd8| ||dkr d9nd:d;d<}d*|d=W S  tk
r| } z&td>t|  d?d@dA W Y S d-}~X Y nX d-S )Bz/Get user activity timeline with detailed eventsr   r	   rv   r[   r   rh  ri  rg  r  r  r  rk  rl  r{   r   )r0   r4   r   r]   r   r4   r   r0   rS  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   ZUntitled)test_case_idr   r   )r  r  r  r  r  r\  r5   
user_loginzUser logged inzbox-arrow-in-rightc                 S   s   | d S rY  r&   rw  r&   r&   r'   ry  R  rz  z9MongoHandler.get_user_activity_timeline.<locals>.<lambda>Tr{  r  Nr   c                 S   s   g | ]}|d  dkr|qS )r  r  r&   r   r%   r&   r&   r'   r  b  s      z;MongoHandler.get_user_activity_timeline.<locals>.<listcomp>c                 S   s   g | ]}|d  dkr|qS )r  )r  r  r&   r  r&   r&   r'   r  c  s      c                 S   s   | d S rY  r&   rw  r&   r&   r'   ry  h  rz  r  c                 S   s   | d S rY  r&   rw  r&   r&   r'   ry  i  rz  r/  c                 S   s   t | d S r<  )r   rw  r&   r&   r'   ry  |  rz  )total_eventstest_case_eventsaccount_eventsevents_per_dayZmost_active_dayZactivity_streakZaccount_activityZCompletezNo activity)Zmost_common_eventr=  Ztimeline_completeness)r}  r~  r  r  timeline_eventsevents_by_dater  r  )r-   timeline_dataz&Error getting user activity timeline: Fz$Failed to retrieve activity timeliner,   )r
   r   rC   r_   r   r`   r   r   r;   rQ   r   r"   ra   r   r{  r  rP  r   r  r   _calculate_activity_streakrI  r#   r   r!   )r$   rX   r}  r
   r   r  r~  Ztest_case_activitiesr)   r  r!  eventr  Zdate_keyr  r  r  Zfirst_eventZ
last_eventZ
first_date	last_dateZdays_betweenr  r  r  r%   r&   r&   r'   get_user_activity_timeline  s     	


	



 
z'MongoHandler.get_user_activity_timelinec                 C   s   |sdS t |dd d}d}d}d}|D ]N}t|d  }|dkrLd}n&|| jdkrd|d7 }nt||}d}|}q(t||}|S )z Calculate user's activity streakr   c                 S   s   | d S rY  r&   rw  r&   r&   r'   ry    rz  z9MongoHandler._calculate_activity_streak.<locals>.<lambda>r  Nr  r[   )r  r
   rP  r  r   r  )r$   r  Zsorted_eventscurrent_streak
max_streakZlast_event_dater  Z
event_dater&   r&   r'   r    s"    


z'MongoHandler._calculate_activity_streakc                 C   s|  z.t | jd|iddddddd}| jd|iddd}|sTddd	W 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r6|d }	|dd d!dd|	d  d"d t	d#d$ |D }
t|
d%kr|d&d'd(t|
 d)d*d+|r|d, d  nd-d.d d/d0d1d2d3h}|

|r|d4d5d6d7d+|r|d, d  nd-d8d |drt |d  j}|d9kr0|d:d;d<d=d>|d td9d?  dd |d@krf|dAdBdCd=d>|d td@d?  d.d |dDkr|dEdFdGd=d>|d tdDd?  dd |rt	 }|D ]}||d   qt|}d
}d
}tt|D ]J}|d
krd}n4|| ||d   jdkr|d7 }nt||}d}qt||}|dHkrh|dIdJdKdLdM|d, d  d.d |d9kr|dNdOdPdLdM|d, d  dd g }t|}|dk r|dQ|dddR|d d dS nV|dk r|dQ|dddT|d d dS n*|dk r&|dQ|dd dU|d d dS t|
dVk r\|dWt|
dVd5dXt|
dV d dS t|}i }i }|D ]Z}|dY }||krd
||< ||  d7  < |dZ }||krd
||< ||  d7  < qpd[}|| d }|t|d|||||d\| ||r
|d
 nd-|r|d
 nd-d]d^}d_|d`W S  tk
rv } z&tdat|  ddbd	 W Y S d-}~X Y nX d-S )cz<Get user achievements and milestones based on their activityrX   r[   r0   r4   r   r]   r4   r0   rS  Frq   r,   r   rN  zFirst StepszGenerated your first test casez	star-fillZ	milestonecommon)r9   r   r  r  r  Zunlocked_atrarityr   	   Zten_test_caseszGetting StartedzGenerated 10 test casesr   1   Zfifty_test_caseszTest Case MasterzGenerated 50 test casesZrarerW  c   Zhundred_test_caseszTest Case ExpertzGenerated 100 test casesZepicc                 s   s    | ]}| d r|d  V  qdS r  rQ   r  r&   r&   r'   r     s     
 zDMongoHandler.get_user_achievements_and_milestones.<locals>.<genexpr>r/  Zmultiple_sourceszVersatile TesterzUsed z different source typesr   Zversatilityr   NZuncommonurlimagejiraazuretextZall_sourceszSource MasterzUsed all available source typesZawardZ	legendaryr  Zmonthly_userzMonthly Userz$Been using the platform for 30+ dayszcalendar-checkZloyaltyr   r  Zquarterly_userzQuarterly Userz$Been using the platform for 90+ daysrl  Zyearly_userzYearly Userz%Been using the platform for 365+ daysrL  Zweekly_streakzWeekly Warriorz"Maintained a 7-day activity streakZfireconsistencyZmonthly_streakzMonthly Masterz#Maintained a 30-day activity streakr   zGenerate 10 test cases)rJ  currenttargetr   r  progresszGenerate 50 test caseszGenerate 100 test casesr  r  zUse all 5 source typesr  r     )Zby_categoryZ	by_rarityZtotal_possible)r,  Znext_achievementZrecent_achievement)total_achievementscompletion_percentageachievementsnext_milestonesr   r  T)r-   achievements_dataz!Error getting user achievements: zFailed to retrieve achievements)r_   r   r`   r   r   r;   r   r   ra   r  
issupersetrQ   r
   rC   r   r   addr  r  r  r  r  _get_achievement_levelr#   r   r!   r"   )r$   rX   r   r)   r  Z
milestonesrN  Ztenth_test_caseZfiftieth_test_caseZhundredth_test_caser  Zall_source_typesZdays_since_registrationZactivity_datesr  Zsorted_datesr  r  r   r  Zcurrent_countr  Zachievement_categoriesZrarity_countsZachievementr  r  Ztotal_possible_achievementsr  r  r%   r&   r&   r'   $get_user_achievements_and_milestones  s    



























z1MongoHandler.get_user_achievements_and_milestonesc                 C   sD   |dkrdS |dkrdS |dkr$dS |dkr0dS |d	kr<d
S dS dS )z4Get achievement level based on completion percentager  Z	Legendaryr  ZMasterr   ZExpert   ZIntermediater   ZBeginnerZNoviceNr&   )r$   r  r&   r&   r'   r    s    z#MongoHandler._get_achievement_levelc           )         s  z|  |sdddW S ddlm}m} | }|dkrJ||dd }nn|d	krb||d
d }nV|dkrz||dd }n>|dkr||dd }n&|dkr||dd }n||dd }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 ]}
| j	d&|
d& iddddd'}|r0|
d$ }|

d(d}|

d)dd* }t|
d+ }d}|
dr||d  j}d}|dkr|dkrt|| d* d*}|t|
d& |d, |d- |
d.d/|t|d0t|d0||t|d0d1d2 q0|rd3d4 |D }d5d4 |D }d6d4 |D }d7d4 |D }tt|t| d0t|t|d0  t|tt|d8  t|tt|d9  d:|rtt|t| d0nd|rt|t|d0  nd|r t|ndd;tt|t| d0t|t|d0  t|tt|d8  d<tt|t| d0t|t|d0  t|tt|d8  d<d=}|D ]Ή t fd>d4|D d }|t|	| d |	 d* dd? d@< t fdAd4|D d }| d@ dB< t|	| d |	 d* d d@ dC<  d@ dD dE  d@ dC dF   dG d) dF  }t|d d@ dH< q|jdIdJ dKdL t|D ]\} |d  d@ dM< qzni }g }|r`|dNdO }|dPdQdRd4 |D   t|dkr |d d@ dH }|d% d@ dH }|| }|dSt|d dT |r`|dU dV } |dW|   |dU dX }!|dY|! dZ g }"|rd[d4 |D }#|#r|"d\t|# d] d^d4 |D }$|$r|"d_t|$ d` |r|d) dV }%|%dak r|"db |dB dV }&|&dck r|"dd || | |	||||"|r*|d ndN|rF|
dUi 
dVdndtded4 |D tdfd4 |D tdgd4 |D tdhd4 |D didjdk	}'dK|'dlW S  tk
r }( z&tdmt|(  ddnd W Y S dN}(~(X Y nX dNS )oz6Get user comparison and benchmarking data (admin only)FrZ   r,   r   r	   rv   r[   r   rh  rL  rg  r  r  r  rk  rl  rm  r4   r{   r  r  r  rn  ro  rp  rq  rr  rs  r  r  r  r  r  )r0   r   rt  ru  r  r  r  r  r   r   r0   r  rt  ru  rW  r  r2   r*   r3   r)   r/  )r  rt  ru  source_type_diversityr7  efficiency_score)rX   r2   r*   r3   metricsc                 S   s   g | ]}|d  d qS r  r  r&   r  r&   r&   r'   r  (  s     zEMongoHandler.get_user_comparison_and_benchmarking.<locals>.<listcomp>c                 S   s(   g | ] }|d  d dkr|d  d qS )r  rt  r   r&   r  r&   r&   r'   r  )  s      c                 S   s   g | ]}|d  d qS )r  ru  r&   r  r&   r&   r'   r  *  s     c                 S   s   g | ]}|d  d qS r  r  r&   r  r&   r&   r'   r  +  s     g      ?g?)r  mediantop_25_percentileZtop_10_percentile)r  r  fastest)r  r  r  )r   Zcompletion_timeru  
efficiencyc                    s(   g | ] }|d  d  d  d kr|qS r  r&   r  r)   r&   r'   r  H  s      )r  test_case_percentilerankingsc                    s(   g | ] }|d  d  d  d kr|qS r  r&   r  r  r&   r'   r  O  s      r
  Zefficiency_percentiler  re  rf  r  overall_scorec                 S   s   | d d S )Nr  r  r&   rw  r&   r&   r'   ry  \  rz  zCMongoHandler.get_user_comparison_and_benchmarking.<locals>.<lambda>Tr{  positionNr1  zTop 3 performers: z, c                 S   s   g | ]}|d  qS )r2   r&   r  r&   r&   r'   r  j  s     z.Performance gap between top and bottom users: z pointsr   r  r  r  zTop 25% threshold: z test casesc                 S   s    g | ]}|d  d dk r|qS )r  r  r   r&   r  r&   r&   r'   r    s      zProvide additional support for z low-performing usersc                 S   s    g | ]}|d  d dkr|qS r  r  r  r&   r  r&   r&   r'   r    s      zRecognize and reward z high-performing usersr  z4Implement training programs to improve success ratesr   z.Provide efficiency training and best practicesc                 S   s    g | ]}|d  d dkr|qS r  r&   r  r&   r&   r'   r    s      c                 S   s0   g | ](}d |d d   kr$dk rn q|qS )r  r  r  r  r&   r  r&   r&   r'   r    s
        c                 S   s0   g | ](}d |d d   kr$dk rn q|qS )r  r  r  r  r&   r  r&   r&   r'   r    s
        c                 S   s    g | ]}|d  d dk r|qS )r  r  r  r&   r  r&   r&   r'   r    s      )r  r  r  r  )Ztop_performerZaverage_performanceZperformance_distribution)	r}  r~  r  r  user_benchmarks
benchmarksr  r  r  )r-   comparison_dataz0Error getting user comparison and benchmarking: z"Failed to retrieve comparison data)rY   r
   r   rC   r_   r   r  r   r   r;   rQ   r   r{  r   r"   r  r  r  r<  r   r  joinra   r#   r   r!   ))r$   rb   r}  r
   r   r  r~  Zuser_performance_datar  r|   Z	user_perfr  r  rt  ru  r  r7  r  Ztest_case_countsZcompletion_timesZsuccess_ratesZefficiency_scoresr  Ztest_case_rankingZefficiency_rankingr  r   r  ru  Z	top_scoreZbottom_scoreZperformance_gapr9  Ztop_25_thresholdr  r  Zhigh_performersr~  Zavg_efficiencyr  r%   r&   r  r'   $get_user_comparison_and_benchmarking  s8   
 



" 



z1MongoHandler.get_user_comparison_and_benchmarkingc              
   C   s  zpt | jd|iddddddd}|s@dddidW S td	d
 |D }t|}g }|dkrp|d |dkr|d |dkr|d |dkr|d |dkr|d tdd |D tdd |D tdd |D tdd |D tdd |D d}dd | D }dd | D }|r@|d nd|||||r^dd |D nd gd!}	d|	dW S  tk
r }
 z&t	
d"t|
  d#d$d% W Y S d&}
~
X Y nX d&S )'z*Get user learning and development insightsrX   r[   r  r4   Tr.   z No test cases found for analysis)r-   learning_insightsc                 s   s    | ]}| d r|d  V  qdS r  r  r  r&   r&   r'   r     s     
 z:MongoHandler.get_user_learning_insights.<locals>.<genexpr>z$Beginner - First test case generatedr  z%Novice - Basic understanding achievedr  zIntermediate - Consistent usager  zAdvanced - Proficient userr   zExpert - Master levelc                 S   s   g | ]}| d dkr|qS )r   r  r  r  r&   r&   r'   r    s      z;MongoHandler.get_user_learning_insights.<locals>.<listcomp>c                 S   s   g | ]}| d dkr|qS )r   r  r  r  r&   r&   r'   r    s      c                 S   s   g | ]}| d dkr|qS )r   r  r  r  r&   r&   r'   r    s      c                 S   s   g | ]}| d dkr|qS )r   r  r  r  r&   r&   r'   r    s      c                 S   s   g | ]}| d dkr|qS )r   r  r  r  r&   r&   r'   r    s      )Zurl_testingZimage_testingZjira_integrationZazure_integrationZtext_analysisc                 S   s   g | ]\}}|d kr|qS )r  r&   r   arear   r&   r&   r'   r    s      c                 S   s   g | ]\}}|d k r|qS )r1  r&   r  r&   r&   r'   r    s      r   zNew Userc                 S   s$   g | ]}d | dd  dqS )z	Focus on rU  rV  z to improve skills)r   r   )r   r  r&   r&   r'   r    s    z)Continue exploring different source types)Zcurrent_stageZlearning_progressionZskill_development	strengthsimprovement_areasr  z!Error getting learning insights: Fz$Failed to retrieve learning insightsr,   N)r_   r   r`   r   r  r   r   r   r#   r   r!   r"   )r$   rX   r   r6  r   Zlearning_stagesZskill_areasr  r  r  r%   r&   r&   r'   get_user_learning_insights  s\     




	
z'MongoHandler.get_user_learning_insightsc              
   C   s   z@|t  tdd t  d}tdd}tj||dd}|W S  tk
r| } zt	dt
|  W Y d	S d	}~X Y nX d	S )
zGenerate JWT token for userr  r   )rX   expiatJWT_SECRET_KEY$your-secret-key-change-in-productionHS256)	algorithmzError generating JWT token: N)r
   rC   r   osgetenvjwtr@   r#   r   r!   r"   )r$   rX   payload
secret_keyrP   r%   r&   r&   r'   rT     s    zMongoHandler.generate_jwt_tokenc              
   C   s
  zt dd}tj||dgd}|d}|rx| jd|i}|rx|ddrxd|d |d	 |d
 |ddddW S dddW S  tjk
r   ddd Y S  tjk
r   ddd Y S  t	k
r } z&t
dt|  ddd W Y S d}~X Y nX dS )z%Verify JWT token and return user infor  r  r   )
algorithmsrX   r0   r6   Tr*   r2   r3   r)   r8   r   FzInvalid or expired tokenr,   zToken expiredzInvalid tokenzError verifying JWT token: zToken verification failedN)r"  r#  r$  decoderQ   r   r;   ZExpiredSignatureErrorZInvalidTokenErrorr#   r   r!   r"   )r$   rP   r&  r%  rX   r)   r%   r&   r&   r'   verify_jwt_token  s,    


zMongoHandler.verify_jwt_tokenc              
   C   sz   z6t | jd|idddddddd|}|W S  tk
rt } z tdt|  g  W Y S d}~X Y nX dS )z&Get all test cases for a specific userrX   r[   )r0   	test_datar4   r   item_idr4   r   zError getting user test cases: N)	r_   r   r`   r   r   r#   r   r!   r"   )r$   rX   r   r   r%   r&   r&   r'   get_user_test_cases  s     z MongoHandler.get_user_test_casesc              
   C   s   zTt t }||t |||i |d}| j| td| d| d|  |W S  t	k
r } z t
dt |  t	dW 5 d}~X Y nX dS )zJSave test case data and generate unique URL with optional user association)r0   r*  r4   url_keyr+  r   r]   rX   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"   rA   rB   r
   rC   r   rD   r   r   r#   r!   )r$   r*  r+  r   rX   	unique_iddocumentr%   r&   r&   r'   save_test_case$  s"    
zMongoHandler.save_test_casec              
   C   s   zT| j d|idd|ii}|jdkr<td|  W dS td|  W dS W n< tk
r } ztd	t|  W Y dS d
}~X Y nX d
S )z5Update the status dictionary for a test case documentr-  rO   r]   r   z%Successfully updated status dict for Tz'No document found to update status for FzError updating status dict: N)	r   rS   ri   r   r   r   r#   r!   r"   )r$   r-  status_valuesrM   r%   r&   r&   r'   update_status_dict9  s    


zMongoHandler.update_status_dictc              
   C   s   zl| d| d| d| d| dt | d| dd}| j| td	| d  W d
S  tk
r } ztdt	|  W Y dS d}~X Y nX dS )z"Track user session and page visitsrd  r^  r]  referrerpage_visitedcountrycity)rd  r^  r]  r4  r5  r  r6  r7  zTracked user session: TzError tracking user session: FN)
rQ   r
   rC   r   rD   r   r   r#   r!   r"   )r$   session_dataZsession_docr%   r&   r&   r'   track_user_sessionJ  s     
zMongoHandler.track_user_sessionc                 C   s   z| d| di | d| d| dt | d| dg | dd	d
	}| drl| d|d< | dr| d|d< | j| td| d  W dS  tk
r } ztdt	|  W Y dS d}~X Y nX dS )z"Track user events and interactionsr  
event_datard  r^  r]  r   test_case_types
item_countr   )	r  r:  rd  r^  r]  r  r   r;  r<  rX   	user_rolezTracked event: TzError tracking event: FN)
rQ   r
   rC   r   rD   r   r   r#   r!   r"   )r$   r:  Z	event_docr%   r&   r&   r'   track_event^  s*    




zMongoHandler.track_eventr  c                 C   s   z|r>|r>t |d}t |dtdd }d||di}nt  t|d }	dd|	ii}|}
|rn||
d< |r||
d< ||d< | j|}| j|
}|
d	d
i}| j|}|
d	di}| j|}d|
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|
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|
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|
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|
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|}|rd4|||t	|d4krf|| dC nd4dC||||r|d4 nd|||dDW S ||||t	|d4kr|| dC nd4dC||||r|d4 nd|||dDW S W n> t
k
r } ztdEt|  W Y dS d}~X Y nX dS )FzZGet analytics summary for the specified date range or number of days with optional filtersr  r[   r   r  r  r{   r   rX   r  generate_button_clickr  rm  z
$addFieldsZeffective_source_typerp  z$andrR  r  Nr  z$event_data.source_type)ifZthenelseT)rQ  rR  rR  r  z$effective_source_typer  r  r  r   r   rP  )r  r;  r  z$test_case_typesz$yearz
$timestampz$monthz$dayOfMonth)rk  rg  rv   )r0   eventsr0   rQ  )r  &event_data.generation_duration_secondsrn  z'$event_data.generation_duration_secondsr  r  )r0   avg_generation_timeZmin_generation_timeZmax_generation_timeZtotal_generations)r0   rD  r   rD  r   )r  rC  r<  Z
item_range$ltez$item_countr  z	1-5 itemsr   z
6-10 itemsr   z11-20 itemsz	20+ itemsz!$event_data.average_time_per_item)r0   rD  Zavg_time_per_itemr   z_id.item_rangerW  )total_sessionsr  generate_clickssuccessful_generationsru  r  Ztest_case_type_distributionr1  Zgeneration_timingtiming_by_sourcetiming_by_itemsperiod_daysz!Error getting analytics summary: )r
   strptimer   rC   r   r   r   r_   r  r{  r#   r   r!   r"   )r$   r~  r  r   r   rX   start_datetimeend_datetimeZdate_filtercutoff_dateZbase_filterrF  r  Zgenerate_filterrG  Zsuccess_filterrH  Zsource_type_pipelineZsource_type_statsZtest_case_type_pipelineZtest_case_type_statsZdaily_activity_pipeliner1  Ztiming_pipelineZtiming_statsZtiming_by_source_pipelinerI  Ztiming_by_items_pipelinerJ  r%   r&   r&   r'   get_analytics_summaryz  s8   











#z"MongoHandler.get_analytics_summaryc              
   C   s   zi }|r| dr$d|d i|d< | drXd|krH|d |d d< nd|d i|d< | drn|d |d< | dr|d |d< t| j|dd	idd
d}|W S  tk
r } ztdt	|  W Y dS d}~X Y nX dS )z,Get detailed analytics with optional filtersr~  r{   r  r  rE  r  r   r0   r   r   i  z"Error getting detailed analytics: N)
rQ   r_   r   r`   r   r   r#   r   r!   r"   )r$   filtersZmatch_criteriarB  r%   r&   r&   r'   get_detailed_analyticsF  s4    



 z#MongoHandler.get_detailed_analyticsc              
   C   s  zj| j d|i}|s.td|  W dS td| d|  tdt|   d|krtdt|d   t|d t	rtd	t|d    n&t|d trtd
t
|d   d}|r8d|kr8d|kr8t }| j d|idd| |d| |ii d}td| d|  d}d|krjt|d trjd}td|  d}d|krt|d t	rd|d krt|d d trd}td|  |rHtd| d|  t }| j d|idd| |d| |ii}	|	jdkr.td|  W dS td|  W dS n"|r |d }
d}t|
D ]\}}|dd}||krbtd|  | j d|idd| d|ii}	|st }| j d|idd| |d| |ii d} qqb|std| d |  W dS W dS d|krRd!|d krR|d d! }
d }d"|kr|d"}t
|d#kr|d  d"|d$  d"|d%  }td&|  t|
D ]\}}|d|d'd}|d(|d)d}|sx|rx|d*}|D ]0}| d+r| d+d } q q|sx|d*}|D ]B}| }|r4|d,sj|d-sj|d.r4|} qxq4|r||krtd/|  | j d|idd0| d1|ii}	|s| j d|idd| |ii |	jdkrtd2|   W dS |rd3|k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rtd5|   W dS |r8||kr8td6|  | j d|idd0| d1|ii}	|s| j d|idd| |ii |	jdkr8td7|   W dS |r|r||d" sn||d8 sn||krtd9| d:|  | j d|idd0| d1|ii}	|s| j d|idd| |ii |	jdkrtd;|   W dS |r||krtd< | j d|idd0| d1|ii}	|rX|sX| j d|idd| |ii |	jdkrtd7|   W dS qt|
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  W S qtd@| d|  W dS tdA| dB W dS W n> tk
r } ztdCt|  W Y dS d }~X Y nX d S )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  rO   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   rU  r1  r[   r/  zExtracted UI identifier: r   Contentcontent
zTitle:TC_ZTC_FUNC_Z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 rV  zFound match for UI identifier z in title: z7Successfully updated status by UI identifier match for zFound match in contentr  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   r_   r   rJ  r   rO  r   r
   rC   rS   ri   r   r  rQ   splitstripr  r   r#   r"   )r$   r-  r  r]   docZtitle_foundcurrent_timeis_shared_viewZis_url_structurerM   r   foundidxr  r   Zui_identifierpartsrV  lineslineZ
base_titler%   r&   r&   r'   update_test_case_statusb  s     	<  


  



 


*


 
z$MongoHandler.update_test_case_statusc              
   C   s   zP| j d|i}|sL| j d|i}|r<td|  ntd|  |W S  tk
r } z tdt|  tdW 5 d}~X Y nX dS )z"Retrieve test case data by URL keyr-  r0   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   r   r#   r!   r"   )r$   r-  rM   r%   r&   r&   r'   get_test_case  s    zMongoHandler.get_test_caseFc                 C   s  zn| j d|i}|sT| j d|i}|r>td|  ntd|  W dS d|krrtd|d   n
td d	|krt|d	 trt|d	 D ]h\}}t|tr|	d
d}|	dd}|rtd| d| d| d qtd| dt
|  qnd	|krt|d	 trd|d	 krt|d	 d D ]`\}}t|tr|	d
|	dd}|	d|	dd}|rtd| d| d| d nt|trzddlm} ||}	|	r<t|	D ]\\}
}|	d
|	dd}|	d|	dd}|rtd| d|
 d| d| d	 qntd| d W n: tk
r } ztd| d|  W 5 d}~X Y nX ntd| dt
|  qHnLd	|krt|d	 trtdt|d	  d|d	 dd  d i W S d|kr2|d r2tdt|d  d  |d W S i }d	|krt|d	 trtd! |d	 D ]B}t|trbd
|krb|	d
d}|	dd}|rb|||< qbnnd	|krt|d	 trd|d	 krtd" |d	 d D ]}t|tr0|	d
|	dd}|	d|	dd}|r|||< nt|trddlm} z`||}|r|D ]H}t|tr\|	d
|	dd}|	d|	dd}|r\|||< q\W n4 tk
r } ztd#|  W 5 d}~X Y nX qn2d	|krt|d	 trd	|d	 krtd$ t|d	 d	 tr|d	 d	 D ]`}t|tr8|	d
|	dd}|	d|	dd}|r8|||< td%| d&| d' q8nzd	|krt|d	 trtd( i W S d	|krt|d	 trd|d	 krt|d	 d trtd) ddlm} z||d	 d }|r|D ]`}t|tr6|	d
|	dd}|	d|	dd}|r6|||< td%| d&| d* q6W n4 tk
r } ztd+|  W 5 d}~X Y nX nDd	|krt|d	 trd|d	 krt|d	 d trtd, ddlm} z|d	 d D ]}t|tr4d-|kr4|d- }|r4t|tr4||}|r4|D ]`}t|trz|	d
|	dd}|	d|	dd}|rz|||< td%| d&| d. qzq4W n4 tk
r } ztd/|  W 5 d}~X Y nX |rRtd0t| d1|  | j d|id2d|ii td3t| d4|  |W S  tk
r } ztd5t|  W Y dS d}~X Y nX dS )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-  r0   re  rf  Nr]   zSTATUS DICT in MongoDB: z"NO STATUS DICT in MongoDB documentr*  rT  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 listrV  z' from list itemzError parsing test_cases list: z%UPDATING status dict in MongoDB with z	 values: rO   z
Returning z status values for z*Error retrieving test case status values: )r   r;   r   r   r   r   r_   r  rO  rQ   rJ  r"   utils.file_handlerrj  r#   r!   r   debugrS   )r$   r-  force_refreshrM   r   r  r   r]   rj  parsedZpidxZptcZptitleZpstatusr%   r2  parsed_test_casesZtest_case_objrV  r&   r&   r'   get_test_case_status_values  s   

  ( ** ,

(

*(
 
(
 &(
$"
z(MongoHandler.get_test_case_status_valuesc              
   C   s   zHt t dd }||t dd}| j| td|  |W S  t	k
r } z t
dt |  t	dW 5 d}~X Y nX dS )z,Save URL parameters and generate a short keyN   shortened_url)r0   
url_paramsr4   rJ  z,Successfully saved URL data with short key: zError saving URL data: z#Failed to save URL data to databaser.  )r$   rt  	short_keyr0  r%   r&   r&   r'   save_url_dataN  s    zMongoHandler.save_url_datac              
   C   s   zH| j d|i}|rDd|kr*|dW S d|kr>|dW S |W S W dS  tk
r } ztd|  W Y dS d}~X Y nX dS )z6
        Retrieve URL parameters by short key
        r0   r*  rt  NzError retrieving URL data: )r   r;   rQ   r#   r   r!   )r$   ru  r0  r%   r&   r&   r'   get_url_data_  s    zMongoHandler.get_url_data)r)   )r)   )r   )Nr   )r   )r[   r   )r4  )r4  )N)NNrW  )NN)Nr   )NN)NrW  )Nrg  )rg  )rg  )rg  )rk  )rg  )rg  )rg  )rg  )rg  )rg  )rg  )rg  )rg  )r   )NNN)NNr  NN)N)F)[__name__
__module____qualname__r(   rI   rN   rU   rY   rc   rl   rm   rp   rt   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r"  r*  r3  r9  r?  rE  rF  rL  rQ  rU  rV  rZ  r_  rb  re  rf  r  r  r  r  r  r  r  r3  rK  rH  rI  rJ  rc  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  rT   r)  r,  r1  r3  r9  r>  rP  rR  rd  rg  rq  rv  rw  r&   r&   r&   r'   r      s   
)*"
%'$/
#
!1
.M6
>G`19)"";H
Q
[3

 

&

$
KZ
~
o

 
 
 =
 8
 Q
 ]
 Or 
 4&9@@#
   
 `;


 M
  !
 >r   )utils.error_loggerr   r   r   r   r   r   r@  r   r   r
   r   r   stringrandomloggingconfig.settingsr   r   rA   r=   r$  r"  	getLoggerrx  r   r   r&   r&   r&   r'   <module>   s"   
