U
    hI                     @   sD  d dl mZmZmZ d dlmZ d dlmZmZm	Z	 d dl
m
Z
mZmZ d dlZd dlZd dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlZe e!Z"e Z#G dd dZ$e#%dddddeefe&e&e&e&edddZ'e#%dddeefe(e	e( e	e( edddZ)dS )    )	APIRouterDependsHTTPException)Session)ListDictOptional)datetime	timedeltatimezoneN)get_db)ActivityRecord)Config)DeveloperDiscovery)FixedDeveloperDiscovery)DynamicActivityWatchClient)ActivityCategorizer)extract_project_infoc                   @   s~   e Zd ZdZedddZdeeeeeddd	Zed
ddZ	eeeeedddZ
eedddZeee dddZdS ) EnvironmentBasedDeveloperServicezMService to handle developer list based on environment - Fixed for existing DB)dbc                 C   s   || _ t|| _d S )N)r   r   	discovery)selfr    r   >/var/www/html/timesheet/backend/fixed_dynamic_developer_api.py__init__   s    z)EnvironmentBasedDeveloperService.__init__FT)scan_network
scan_localscan_databaseforce_refreshreturnc                 C   s$   t  r|  S | ||||S dS )z>Get developers list based on environment (local vs production)N)r   is_local_get_local_developer_only_get_all_developers)r   r   r   r   r   r   r   r   get_developers_list   s    z4EnvironmentBasedDeveloperService.get_developers_list)r   c                 C   s6  zt  }tjp|}ddlm} | j|dd|i }|rR|d }|d }n|}t	
d| d | j }g }|r|D ]v}|d|d	  |||d
 |d	 ddd|d| d|d	  || |ttj |dd|ddd q~n~| |}	|d| ||dd|	dkr$dnd|	dkr4dnd|	dkrLd|	 dnd|||	| ||	dkrjdnddd |dt|ttj |dt kr|n|dW S  tk
r0 }
 zht	d|
  d tjt  ddddd!t  tjdd"dddgddttj tjt|
d# W Y S d"}
~
X Y nX d"S )$z'Return only the current local developerr   textz
                SELECT developer_id, name 
                FROM developers 
                WHERE name = :dev_name OR developer_id = :dev_name
                LIMIT 1
            dev_name   zLocal developer 'z' not found in developers tableZlocal_porthostonlinelocalzLocal ActivityWatch instance	device_id_versionunknownbucket_count)idnamehostnamer)   r(   statussourcedescriptionr,   developer_idactivity_count	last_seenr.   r0   Z	local_db_	localhosti  database_onlyofflinedatabasezLocal developer (z activities in database)zLocal developer (no data yet)local_developer_id)
developersenvironmenttotal_countdiscovered_atlocal_developerr>   zError getting local developer: Zlocal_fallbackz Local developer (database error)N)r?   r@   rA   rB   rC   error)socketgethostnamer   LOCAL_DEVELOPER_NAME
sqlalchemyr%   r   executefetchoneloggerwarningr   discover_local_instancesappendget_get_activity_count_safer	   nowr   utc	isoformat_get_last_activity_time_safelenlocals	ExceptionrD   str)r   Zlocal_hostnameZlocal_developer_namer%   
dev_resultr>   Zlocal_instancesr?   instanceZdb_activity_counter   r   r   r!   '   s    
 





	z:EnvironmentBasedDeveloperService._get_local_developer_onlyc           	   
   C   s   zt d | jj|||d}|D ]l}|dp8|d}| ||d< |ds"| ||d< |d r"t|d tr|d 	 n|d |d< q"|dt
|ttj	 dd	W S  tk
r } z*t d
|  tddt| dW 5 d}~X Y nX dS )z5Get all developers from all sources (production mode)z&Performing full developer discovery...)r   r   r   r7   r1   r8   r9   
productionF)r?   r@   rA   rB   Z
from_cachez"Error discovering all developers:   zError discovering developers: status_codedetailN)rK   infor   discover_all_developersrO   rP   rT   
isinstancer	   rS   rU   rQ   r   rR   rW   rD   r   rX   )	r   r   r   r   r   discovered_developersdevdev_idr[   r   r   r   r"      s.    

(z4EnvironmentBasedDeveloperService._get_all_developers)developer_id_or_namer   c           
   
   C   s   zjddl m}m} | j|d||d }|rb|d }| j|dd|i}| }|p^dW S W dS W n tk
r } zjt	d| d|  z:| j|d	}| }	t
d
|	  |	pdW  W Y S    Y W Y 
dS X W 5 d}~X Y nX dS )z)Safely get activity count for a developerr   )funcr%   
                SELECT developer_id 
                FROM developers 
                WHERE developer_id = :dev_id OR name = :dev_name
                LIMIT 1
            rf   r&   z
                    SELECT COUNT(*) 
                    FROM activity_records 
                    WHERE developer_id = :dev_id
                rf   z!Error getting activity count for : z%SELECT COUNT(*) FROM activity_recordsz Returning total activity count: N)rH   rh   r%   r   rI   rJ   scalarrW   rK   rL   ra   )
r   rg   rh   r%   rY   r7   resultcountr[   totalr   r   r   rP      s4    
 

z9EnvironmentBasedDeveloperService._get_activity_count_safec              
   C   s   znddl m} | j|d||d }|rf|d }| j|dd|i}| }|r`| ndW S W dS W n> tk
r } z t	d| d	|  W Y dS d}~X Y nX dS )
z-Safely get last activity time for a developerr   r$   ri   rj   z
                    SELECT MAX(timestamp)
                    FROM activity_records 
                    WHERE developer_id = :dev_id
                rf   Nz%Error getting last activity time for rk   )
rH   r%   r   rI   rJ   rl   rS   rW   rK   rL   )r   rg   r%   rY   r7   rm   Z	last_timer[   r   r   r   rT      s(    
 
z=EnvironmentBasedDeveloperService._get_last_activity_time_safeN)FTTF)__name__
__module____qualname____doc__r   r   boolr   r#   r!   r"   rX   intrP   r   rT   r   r   r   r   r      s(        k  "+r   z/developersFT)r   r   r   r   r   c                    s   t |}|| |||S )z(Get developers list based on environment)r   r#   )r   r   r   r   r   servicer   r   r   r#     s    	r#   z/activity-data/{developer_id})r7   
start_dateend_dater   c              
      s  zt  }|r"t|dd}nttjjddddd}|rTt|dd}nttj}t|}| }t	fdd|d D d  st
d	d
dg }	d}
 d dkr6zDt }| r|||}	d}
td d  dt|	 d W n> tk
r4 } ztd d  d|  W 5 d}~X Y nX |	szrddlm} ||d dpf d ||d } fdd|D }	d}
td d  dt|	 d W n8 tk
r } ztd|  g }	W 5 d}~X Y nX |	D ]}|ds@t|}|dpd|d< |dp&d |d< |d!p:d"|d!< ||d#d$|d%d$}|d& |d&< |d' |d'< |d( |d)< qddd*ddd*ddd*ddd*ddd*d+}|	D ]L}|d&d,}||kr|| d-  d.7  < || d/  |d/d7  < qtd0d |	D }|D ]@}|dkrLt|| d/ | d1 d.|| d2< nd|| d2< q|	 |
|| | d3t|	|d4W S  tk
r } z0td5 d|  t
d6d7t| dW 5 d}~X Y nX dS )8z*Get activity data for a specific developerZz+00:00r   )hourminutesecondmicrosecondc                 3   s   | ]}|d   kr|V  qdS )r1   Nr   ).0d)r7   r   r   	<genexpr>+  s      z.get_developer_activity_data.<locals>.<genexpr>r?   Ni  zDeveloper not foundr^   r=   r4   r*   ZactivitywatchzRetrieved live data for r2   rk   z activitieszFailed to get live data for r$   a  
                    SELECT 
                        ar.application_name,
                        ar.window_title,
                        ar.duration,
                        ar.timestamp,
                        ar.category,
                        ar.detailed_activity,
                        ar.url,
                        ar.file_path,
                        ar.developer_id,
                        ar.project_name,
                        ar.project_type,
                        ar.project_file,
                        d.name as developer_name
                    FROM activity_records ar
                    LEFT JOIN developers d ON ar.developer_id = d.developer_id
                    WHERE ar.developer_id = :dev_id
                    AND ar.timestamp >= :start_date
                    AND ar.timestamp <= :end_date
                    ORDER BY ar.duration DESC
                    LIMIT 1000
                r7   )rf   rw   rx   c                    sr   g | ]j}|j |jp d  |j|j|jp(d|jr8|j nd|jpBd|jpL|j|j	pTd|j
p\d|j|j|jdqS )r2   r   NZOther )r7   developer_nameapplication_namewindow_titleduration	timestampcategorydetailed_activityurl	file_pathproject_nameproject_typeproject_file)r7   r   r   r   r   r   rS   r   r   r   r   r   r   r   )r~   record)	developerr   r   
<listcomp>`  s   
z/get_developer_activity_data.<locals>.<listcomp>zRetrieved database data for z Error getting database records: r   Z
Unassignedr   ZGeneralr   ZActivityr   r   r   r   Zsubcategory
confidenceZcategory_confidence)rn   r   )Z
productivebrowserserverznon-workuncategorizedr   rn   r'   r   c                 s   s   | ]}|d  V  qdS )r   Nr   )r~   itemr   r   r   r     s     d   
percentage)startend)datar   data_source
total_time
date_ranger8   category_summaryz Error getting activity data for r]   zError getting activity data: )r   r	   fromisoformatreplacerQ   r   rR   r   r#   nextr   r   test_connectionget_activity_datarK   ra   rU   rW   rL   rH   r%   rI   rO   fetchallrD   r   Zget_detailed_categorysumroundrS   rX   )r7   rw   rx   r   Zcategorizerr   r   rv   developers_resultactivity_datar   clientr[   r%   Z
db_recordsactivityproject_infoZcategory_infor   cattotal_durationr   )r   r7   r   get_developer_activity_data  s    $,

$


 
$
r   )*fastapir   r   r   sqlalchemy.ormr   typingr   r   r   r	   r
   r   osloggingr=   r   modelsr   configr   developer_discoveryr   Zfixed_developer_discoveryr   Zdynamic_activitywatch_clientr   Zactivity_categorizerr   improved_project_extractorr   rE   	getLoggerrp   rK   routerr   rO   rt   r#   rX   r   r   r   r   r   <module>   sR   
 p