
    !/i*0                        U d Z ddlZddlZddlZddlZddlmZ ddlmZm	Z	m
Z
mZ ddlmZ ddlZddlZi Zeed<    ej$                         Zdedej$                  fd	Z	 	 d?d
e
eef   de
eef   dededef
dZ	 	 d@d
e
eef   dedededef
dZ	 	 dAd
e
eef   dededefdZ	 dBd
e
eef   dedefdZ	 	 dCd
e
eef   deegef   dededef
dZ	 dBd
e
eef   de	e   defdZdDde
eef   dedefdZ G d d      Z e!d k(  rddl"Z" e#e"jH                        d!kD  re"jH                  d!   Z%e%d"k(  r e&d#        ed$      Z' e&d%       d ejP                         jS                         d&Z* ee'e*      Z+ e&d'e+rd(nd)         e&d*        ee'      Z, e&d+e,rd(nd)         e&d,e,         e&d-       d. Z- ee'e-      Z+ e&d/e+rd(nd)         e&d0        ee'      Z. e&d1e.        e'j_                          e'ja                  d2      Z1e1je                         re1j_                           e&d3       ye%d4k(  r; e#e"jH                        dkD  re"jH                  d   nd5Z3 ee3      Z4 e&d6e4 d7       ye%d8k(  rN e#e"jH                        dkD  r0 ee"jH                  d         Z5 e& ejl                  e5d9             y e&d:       y e&d;e%         e&d<       y e&d=        e&d>       yy)Ea  
Genesis Atomic I/O
==================
Atomic file operations to prevent data corruption.

Uses the "write to temp, then rename" pattern for atomic writes.
Prevents partial writes and ensures data integrity.

Usage:
    from atomic_io import atomic_write, atomic_json_write, safe_read

    # Atomic write
    atomic_write("/path/to/file.txt", "content")

    # Atomic JSON write
    atomic_json_write("/path/to/data.json", {"key": "value"})

    # Safe read with fallback
    data = safe_read("/path/to/file.txt", default="")
    N)Path)AnyOptionalUnionCallable)datetime_file_lockspathreturnc                     t         5  | t        vrt        j                         t        | <   t        |    cddd       S # 1 sw Y   yxY w)z.Get or create a lock for a specific file path.N)_lock_managerr	   	threadingLock)r
   s    '/mnt/e/genesis-system/core/atomic_io.py_get_file_lockr   %   s;    	 !{" ) 0K4 ! ! !s	   ,=A	file_pathcontentmodebackupc                 *   t        |       } t        t        |             }|5  	 | j                  j	                  dd       t        j                  | j                  d| j                   dd      \  }}	 t        j                  ||      5 }|j                  |       |j                          t        j                  |j                                ddd       |rD| j                         r4| j                  | j                    d      }t#        j$                  | |       t        j&                  d	k(  r7| j                         r| j)                          t        j*                  ||        nt        j*                  ||        	 ddd       y# 1 sw Y   xY w# t,        $ r:}	t        j.                  j                  |      rt        j(                  |        d}	~	ww xY w# t,        $ r#}	t1        d
|  d|	        Y d}	~	ddd       yd}	~	ww xY w# 1 sw Y   yxY w)a  
    Atomically write content to a file.

    Uses temp file + rename pattern for atomicity.
    Creates backup of existing file.

    Args:
        file_path: Target file path
        content: Content to write (str or bytes)
        mode: Write mode ('w' for text, 'wb' for binary)
        backup: Create .bak backup of existing file

    Returns:
        True if successful, False otherwise
    Tparentsexist_ok._.tmpdirprefixsuffixN.bakntz[!] Atomic write failed for : F)r   r   strparentmkdirtempfilemkstempstemosfdopenwriteflushfsyncfilenoexistswith_suffixr    shutilcopy2nameunlinkrename	Exceptionr
   print)
r   r   r   r   locktemp_fd	temp_pathfbackup_pathes
             r   atomic_writer?   -   s   * YI#i.)D	 +*	""4$"? "*!1!1$$9>>*!,"GYYYw- )GGG$GGIHHQXXZ() i..0"+"7"79;K;K:LD8Q"RKLLK8 77d? '')!((*IIi3IIi3C+ +) )*  77>>),IIi(	  	02aSABW+ +R	S+ +sg   H	AG5FAFB.FF	F	G5GGG	H#H4H	HH		H   dataindentc                     	 t        j                  ||t              }t        | |d|      S # t        $ r}t        d|        Y d}~yd}~ww xY w)a  
    Atomically write JSON data to a file.

    Args:
        file_path: Target file path
        data: JSON-serializable data
        indent: JSON indentation (default 2)
        backup: Create backup of existing file

    Returns:
        True if successful, False otherwise
    )rB   defaultw)r   r   z[!] Atomic JSON write failed: NF)jsondumpsr$   r?   r7   r8   )r   rA   rB   r   r   r>   s         r   atomic_json_writerH   s   sM    $**T&#>IwSHH .qc23s   *- 	AA		ArD   c                     t        |       } 	 | j                         s|S t        | |      5 }|j                         cddd       S # 1 sw Y   yxY w# t        $ r}t        d|  d|        |cY d}~S d}~ww xY w)z
    Safely read a file with fallback to default.

    Args:
        file_path: File to read
        default: Default value if file doesn't exist or read fails
        mode: Read mode

    Returns:
        File content or default value
    Nz[!] Safe read failed for r#   )r   r0   openreadr7   r8   )r   rD   r   r<   r>   s        r   	safe_readrL      sy      YI	!N)T" 	a668	 	 	  ))Bqc:;s>   A A A	A A
A A 	A7A2,A72A7c                     t        | d      }||S 	 t        j                  |      S # t        j                  $ r}t	        d|  d|        |cY d}~S d}~ww xY w)z
    Safely read JSON from a file with fallback.

    Args:
        file_path: JSON file to read
        default: Default value if read fails

    Returns:
        Parsed JSON or default value
    NrD   z[!] JSON decode failed for r#   )rL   rF   loadsJSONDecodeErrorr8   )r   rD   r   r>   s       r   safe_json_readrQ      s_     	40Gzz'"" +I;b<=s   ( AAAA	update_fnis_jsonc                 `   t        |       } t        t        |             }|5  	 |rt        | |      }nt	        | |      } ||      }|rt        | |      cddd       S t        | |      cddd       S # t        $ r#}t        d|  d|        Y d}~ddd       yd}~ww xY w# 1 sw Y   yxY w)a;  
    Atomically read, update, and write a file.

    Args:
        file_path: File to update
        update_fn: Function that takes current content and returns new content
        default: Default value if file doesn't exist
        is_json: Whether file is JSON format

    Returns:
        True if successful
    rN   Nz[!] Atomic update failed for r#   F)	r   r   r$   rQ   rL   rH   r?   r7   r8   )r   rR   rD   rS   r9   currentupdatedr>   s           r   atomic_updaterW      s    $ YI#i.)D	 	(GD#Iw?  (G (G<  $Iw7 "  	1)BqcBC' "	# s4   B$2A5 A55	B!>BB$B!!B$$B-expected_hashc                    t        |       } dddddd}| j                         s|S d|d<   | j                         j                  |d<   	 t	        | d      5 }|j                         }d|d	<   t        j                  |      j                         |d
<   |r|d
   |k(  |d<   nd|d<   ddd       |S # 1 sw Y   |S xY w# t        $ r}t        |      |d<   Y d}~|S d}~ww xY w)z
    Verify file integrity.

    Args:
        file_path: File to verify
        expected_hash: Optional expected SHA256 hash

    Returns:
        Dict with exists, readable, hash, valid fields
    FNr   )r0   readablehashvalidsizeTr0   r]   rbrZ   r[   r\   error)r   r0   statst_sizerJ   rK   hashlibsha256	hexdigestr7   r$   )r   rX   resultr<   r   r>   s         r   verify_integrityrf      s     YIF F8^^%--F6N!)T" 	'affhG!%F:$^^G4>>@F6N"(.M"Aw"&w	' M	' M  !a&wM!s7   	B; AB.$B; .B83B; 8B; ;	CCC	directorymax_age_hoursc                 n   t        |       } | j                         syd}t        j                         j	                         |dz  z
  }| j                  d      D ]5  }	 |j                         j                  |k  r|j                          |dz  }7 |dkD  rt        d| d|         |S # t        $ r Y [w xY w)z
    Clean up orphaned temp files from failed atomic writes.

    Args:
        directory: Directory to clean
        max_age_hours: Max age of temp files to keep

    Returns:
        Number of files cleaned
    r   i  z.*_*.tmp   z[OK] Cleaned z orphaned temp files from )r   r0   r   now	timestampglobr`   st_mtimer5   r7   r8   )rg   rh   cleanedcutoff	temp_files        r   cleanup_temp_filesrr     s     YIG\\^%%'=4+?@F^^J/ 		~~((61  "1	 {gY&@LMN  		s   2B((	B43B4c                   @    e Zd ZdZ	 	 d	deeef   dedefdZd Z	d Z
y)

AtomicFilez
    Context manager for atomic file writes.

    Usage:
        with AtomicFile("/path/to/file.txt") as f:
            f.write("content")
        # File is atomically written on context exit
    r   r   r   c                 j    t        |      | _        || _        || _        d | _        d | _        d | _        y N)r   r   r   r   r:   r;   _file)selfr   r   r   s       r   __init__zAtomicFile.__init__G  s2     i	
    c                 h   | j                   j                  j                  dd       t        j                  | j                   j                  d| j                   j
                   dd      \  | _        | _        t        j                  | j                  | j                        | _        | j                  S )NTr   r   r   r   r   )r   r%   r&   r'   r(   r)   r:   r;   r*   r+   r   rw   )rx   s    r   	__enter__zAtomicFile.__enter__T  s    ##D4#@'/'7'7%%t~~**+1-(
$dn YYt||TYY7
zzrz   c                     	 | j                   ra| j                   j                          t        j                  | j                   j	                                | j                   j                          || j                  rl| j                  j                         rR| j                  j                  | j                  j                   d      }t        j                  | j                  |       t        j                  dk(  r4| j                  j                         r| j                  j                          t        j                  | j                   | j                         yt        j"                  j                  | j                         rt        j                  | j                          y# t$        $ r`}t'        d|        t        j"                  j                  | j                         rt        j                  | j                          Y d }~yd }~ww xY w)Nr!   r"   z[!] AtomicFile cleanup error: F)rw   r-   r*   r.   r/   closer   r   r0   r1   r    r2   r3   r4   r5   r6   r;   r
   r7   r8   )rx   exc_typeexc_valexc_tbr=   r>   s         r   __exit__zAtomicFile.__exit__`  sV   	*zz

  "**,-

  ";;4>>#8#8#:"&.."<"<@U@U?VVZ=["\KLL=77d?t~~'<'<'>NN))+		$..$..9  77>>$..1IIdnn-   	*21#67ww~~dnn-		$..)	*s    EF$ AF$ $	H-AHHNrE   T)__name__
__module____qualname____doc__r   r$   r   boolry   r|   r    rz   r   rt   rt   =  sC     	d#  	
rz   rt   __main__rj   testz=== Atomic I/O Test ===
z/tmp/atomic_test.jsonzTesting atomic JSON write...)r   rl   z	  Write: OKFAILEDzTesting safe JSON read...z  Read: z  Data: zTesting atomic update...c                     d| d<   | S )NTrV   r   )ds    r   	add_fieldr     s    #)rz   z
  Update: zVerifying integrity...z  Integrity: z	.json.bakz
[OK] All tests passedcleanupr   zCleaned z temp filesverify)rB   z(Usage: python atomic_io.py verify <file>zUnknown command: z0Usage: python atomic_io.py [test|cleanup|verify]zGenesis Atomic I/Oz=Usage: python atomic_io.py [test|cleanup <dir>|verify <file>]r   )r@   T)Nrrv   )NT)   )7r   r*   rF   r'   r2   pathlibr   typingr   r   r   r   r   r   rb   r	   dict__annotations__r   r   r$   r   bytesr   r?   intrH   rL   rQ   rW   rf   rr   rt   r   syslenargvcmdr8   	test_filerk   	isoformatrA   success	read_datar   	integrityr5   r1   r   r0   rg   ro   re   rG   r   rz   r   <module>r      s  * 
     1 1    T 	 ! ! ! 	CS$YC3:C C 	C
 
CR 	S$Y
  	
 
8 S$Y  		@ S$Y 	8 	(S$Y(s
#( ( 	(
 
(Z $(+S$Y+C=+ 
+\%T	"2 3 PS @> >D z
388}qhhqk&=-.45I 01"1I1I1KLD'	48GIgd8<=> -.&y1IHYTH=>?HYK() ,- $Iy9GJwtH=>? *+(3IM)-. **;7F}}+,I'*388}q'8cI(3GHWI[12H_388}q )#((1+6jdjj23@A %cU+,DE"#MN{ rz   