
    mi*                         d Z ddlZddlmZmZ ddlmZmZmZmZ ddl	m
Z
 ddlmZ ddlmZ  ee          Z G d d	          ZdS )
zr
Data access layer for health database.

Provides CRUD operations for sync records, sync state, and data indexes.
    N)datedatetime)ListOptionalDictAny)Path)get_connection)setup_loggerc                      e Zd ZdZd&dee         ddfdZdej        fdZ		 	 d'de
d	ed
ede
dedee
         defdZ	 	 d(dee
         dedeee
ef                  fdZde
dee         fdZ	 d&de
dedee         ddfdZdee
ee
ef         f         fdZ	 d)de
dedededdf
dZde
dedee
         fdZ	 	 d*de
de
d eded!ee         d"ee         ddfd#Zd	ed
edeee
ef                  fd$Zde
defd%ZdS )+HealthRepositoryz/Repository for health data database operations.Ndb_pathreturnc                     || _         dS )zbInitialize repository.

        Args:
            db_path: Optional path to database file
        N)r   )selfr   s     -/root/projects/butler/health/db/repository.py__init__zHealthRepository.__init__   s         c                 *    t          | j                  S )zQGet database connection.

        Returns:
            SQLite connection
        )r
   r   )r   s    r   	_get_connzHealthRepository._get_conn   s     dl+++r   r   	data_type
start_dateend_datestatusrecords_syncederror_messagec           
      <   |                                  5 }|                                }|                    d||                                |                                |||f           |                                 |j        cddd           S # 1 swxY w Y   dS )a  Create a new sync record.

        Args:
            data_type: Type of data synced
            start_date: Start date of sync range
            end_date: End date of sync range
            status: Sync status ('success', 'failed', 'partial')
            records_synced: Number of records successfully synced
            error_message: Optional error message if sync failed

        Returns:
            ID of created record
        z
                INSERT INTO sync_records
                (data_type, start_date, end_date, status, records_synced, error_message)
                VALUES (?, ?, ?, ?, ?, ?)
                N)r   cursorexecute	isoformatcommit	lastrowid)	r   r   r   r   r   r   r   connr   s	            r   create_sync_recordz#HealthRepository.create_sync_record'   s    , ^^ 	$[[]]FNN ((**&&(("!   KKMMM#%	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$s   A/BBBd   limitc                 &   |                                  5 }|                                }|r|                    d||f           n|                    d|f           d |                                D             cddd           S # 1 swxY w Y   dS )zGet sync records, optionally filtered by data type.

        Args:
            data_type: Optional data type filter
            limit: Maximum number of records to return

        Returns:
            List of sync record dictionaries
        z
                    SELECT * FROM sync_records
                    WHERE data_type = ?
                    ORDER BY created_at DESC
                    LIMIT ?
                    z
                    SELECT * FROM sync_records
                    ORDER BY created_at DESC
                    LIMIT ?
                    c                 ,    g | ]}t          |          S  dict.0rows     r   
<listcomp>z5HealthRepository.get_sync_records.<locals>.<listcomp>v       ;;;#DII;;;r   Nr   r   r   fetchall)r   r   r&   r#   r   s        r   get_sync_recordsz!HealthRepository.get_sync_recordsQ   s     ^^ 	<[[]]F  &    
 H   <;):):;;;/	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	<   A$BB
B
c                 T   |                                  5 }|                                }|                    d|f           |                                }|r8t	          j        |d                                                   cddd           S 	 ddd           dS # 1 swxY w Y   dS )zGet the last sync date for a data type.

        Args:
            data_type: Type of data

        Returns:
            Last sync date, or None if never synced
        z>SELECT last_sync_date FROM last_sync_state WHERE data_type = ?last_sync_dateN)r   r   r   fetchoner   fromisoformatr   )r   r   r#   r   r.   s        r   get_last_sync_datez#HealthRepository.get_last_sync_datez   s    ^^ 
	[[]]FNNP   //##C L-c2B.CDDIIKK
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	s   A-BBB!$B!r6   total_recordsc                    |                                  5 }|                                }|                    d|f           |                                }|rY|,|                    d|                                ||f           nX|                    d|                                |f           n-|                    d||                                |pdf           |                                 ddd           dS # 1 swxY w Y   dS )zUpdate the last sync state for a data type.

        Args:
            data_type: Type of data
            last_sync_date: Last successfully synced date
            total_records: Optional total record count to set
        z=SELECT total_records FROM last_sync_state WHERE data_type = ?Nz
                        UPDATE last_sync_state
                        SET last_sync_date = ?, total_records = ?, updated_at = CURRENT_TIMESTAMP
                        WHERE data_type = ?
                        z
                        UPDATE last_sync_state
                        SET last_sync_date = ?, updated_at = CURRENT_TIMESTAMP
                        WHERE data_type = ?
                        z
                    INSERT INTO last_sync_state (data_type, last_sync_date, total_records)
                    VALUES (?, ?, ?)
                    r   )r   r   r   r7   r    r!   )r   r   r6   r:   r#   r   r.   s          r   update_last_sync_statez'HealthRepository.update_last_sync_state   s{    ^^ (	[[]]F NNO   //##C  ,NN
 (1133]IN    NN
 (1133Y?      8 8 : :M<NQO   KKMMMQ(	 (	 (	 (	 (	 (	 (	 (	 (	 (	 (	 (	 (	 (	 (	 (	 (	 (	s   CC>>DDc                 (   |                                  5 }|                                }|                    d           i }|                                D ]#}|d         |d         |d         d||d         <   $|cddd           S # 1 swxY w Y   dS )zyGet last sync state for all data types.

        Returns:
            Dictionary mapping data_type to state info
        zSELECT * FROM last_sync_stater6   r:   
updated_at)r6   r:   r>   r   Nr1   )r   r#   r   resultr.   s        r   get_all_last_sync_statesz)HealthRepository.get_all_last_sync_states   s     ^^ 	[[]]FNN:;;;F((  &)*:&;%(%9"%l"3, ,s;'(( 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   A%BBBTmetric_typemetric_date	file_pathhas_datac           	      "   |                                  5 }|                                }|                    d||                                t	          |          |f           |                                 ddd           dS # 1 swxY w Y   dS )zIndex a daily metric file.

        Args:
            metric_type: Type of metric
            metric_date: Date of the metric
            file_path: Path to JSON file
            has_data: Whether the file contains valid data
        z
                INSERT OR REPLACE INTO daily_metrics_index
                (metric_type, date, file_path, has_data)
                VALUES (?, ?, ?, ?)
                Nr   r   r   r    strr!   )r   rA   rB   rC   rD   r#   r   s          r   index_daily_metricz#HealthRepository.index_daily_metric   s     ^^ 	[[]]FNN  ))++	NN	   KKMMM	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   A"BBBc                    |                                  5 }|                                }|                    d||                                f           |                                }|r|d         ndcddd           S # 1 swxY w Y   dS )zGet file path for a daily metric.

        Args:
            metric_type: Type of metric
            metric_date: Date of the metric

        Returns:
            File path string, or None if not found
        z~
                SELECT file_path FROM daily_metrics_index
                WHERE metric_type = ? AND date = ?
                rC   N)r   r   r   r    r7   )r   rA   rB   r#   r   r.   s         r   get_daily_metric_pathz&HealthRepository.get_daily_metric_path   s     ^^ 	5[[]]FNN k33556   //##C'*43{##	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5s   AB  BBactivity_idactivity_typeactivity_dateduration_secondsdistance_metersc                 &   |                                  5 }|                                }|                    d|||                                ||t	          |          f           |                                 ddd           dS # 1 swxY w Y   dS )aQ  Index an activity file.

        Args:
            activity_id: Unique activity ID
            activity_type: Type of activity
            activity_date: Date of the activity
            file_path: Path to JSON file
            duration_seconds: Optional activity duration
            distance_meters: Optional activity distance
        z
                INSERT OR REPLACE INTO activity_index
                (activity_id, activity_type, date, duration_seconds, distance_meters, file_path)
                VALUES (?, ?, ?, ?, ?, ?)
                NrF   )	r   rK   rL   rM   rC   rN   rO   r#   r   s	            r   index_activityzHealthRepository.index_activity  s    & ^^ 	[[]]FNN  !!++--$#	NN   KKMMM#	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	r4   c                 :   |                                  5 }|                                }|                    d|                                |                                f           d |                                D             cddd           S # 1 swxY w Y   dS )zGet all activities within a date range.

        Args:
            start_date: Start date
            end_date: End date

        Returns:
            List of activity index records
        z
                SELECT * FROM activity_index
                WHERE date >= ? AND date <= ?
                ORDER BY date DESC
                c                 ,    g | ]}t          |          S r)   r*   r,   s     r   r/   zAHealthRepository.get_activities_by_date_range.<locals>.<listcomp>T  r0   r   N)r   r   r   r    r2   )r   r   r   r#   r   s        r   get_activities_by_date_rangez-HealthRepository.get_activities_by_date_range=  s     ^^ 	<[[]]FNN
 %%''););)=)=>   <;):):;;;	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	<s   A.BBBc                     |                                  5 }|                                }|                    d|f           |                                ducddd           S # 1 swxY w Y   dS )zCheck if an activity is already indexed.

        Args:
            activity_id: Activity ID to check

        Returns:
            True if activity exists in index
        z2SELECT 1 FROM activity_index WHERE activity_id = ?N)r   r   r   r7   )r   rK   r#   r   s       r   activity_existsz HealthRepository.activity_existsV  s     ^^ 	1[[]]FNND   ??$$D0	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1s   AA##A'*A')N)r   N)Nr%   )T)NN)__name__
__module____qualname____doc__r   r	   r   sqlite3
Connectionr   rG   r   intr$   r   r   r   r3   r9   r<   r@   boolrH   rJ   floatrQ   rT   rV   r)   r   r   r   r      s       99  $    ,7- , , , ,   '+($ ($($ ($ 	($
 ($ ($  }($ 
($ ($ ($ ($X $(%< %<C=%< %< 
d38n		%< %< %< %<RC HTN    2 (,	5 55 5  }	5
 
5 5 5 5n$sDcN/B*C    6    	
  
   @55-15	#5 5 5 5B +/+/$ $$ $ 	$
 $ #3-$ "%$ 
$ $ $ $L<<*.<	d38n	< < < <213 14 1 1 1 1 1 1r   r   )rZ   r[   r   r   typingr   r   r   r   pathlibr	   health.db.schemar
   health.utils.logging_configr   rW   loggerr   r)   r   r   <module>re      s      # # # # # # # # , , , , , , , , , , , ,       + + + + + + 4 4 4 4 4 4	h		S1 S1 S1 S1 S1 S1 S1 S1 S1 S1r   