o
    i#                     @  s  d Z ddlm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mZ zddlmZ ddlmZ ddlmZ dd	lmZ W nH ey Z z<ejpNd
ZedkrYedsY ejejeZej edZ!e"dej# dej# dej# de! d	ej$d e%dddZ[ww e&Z'e&Z(e	e'e)e(e&f f Z*d@ddZ+dAddZ,dBd"d#Z-dCd%d&Z.dDd)d*Z/dEd-d.Z0dFd0d1Z1dGd3d4Z2		5dHdId:d;Z3dJd=d>Z4e5d?kre%e4 dS )Ku  
Print Rich tables of .T04 file alignment by 12-char timestamp
(last 12 characters of the basename before .T04) for given directories.
The receiver/source prefix is auto-discovered as everything in the basename
before that 12-character timestamp.

By default, immediate subdirectories of the script’s folder are scanned; pass
``DIR`` paths or set ``--root`` to change that. See ``--help``.
    )annotationsN)defaultdict)DefaultDictIterableListSetTuple)box)Consoleescape)Table richzrich.zrequirements.txtz[The 'rich' package is not installed for the Python you used to run this script.
  Python:  zA
  Fix:     install into that same environment, e.g.
            zM -m pip install rich
           or, from this project directory:
            z -m pip install -r zT

  (Running plain `pip install` can target a different interpreter than `python3`.)file   by_tsByTimestampreturnList[Prefix]c                 C  s   dd |   D }t|S )Nc                 S  s   h | ]	}|D ]}|qqS  r   ).0mpr   r   P/home/russ/Documents/_GNSS_data/2026/SUMO-416_Static_Hex/gnss_timestamp_table.py	<setcomp>1   s    z#collect_prefixes.<locals>.<setcomp>)valuessorted)r   sr   r   r   collect_prefixes0   s   r    pfxPrefixstrc                 C  s   | r| nd}t |S )Nz<empty prefix>r   )r!   r   r   r   r   format_col_header5   s   r$   nameTuple[Prefix, Timestamp] | Nonec                 C  sV   |   ds	d S | d d }t|dk rd S |dd  }| s#d S |d d |fS )Nz.t04   i)lowerendswithlenisdigit)r%   stemtsr   r   r   parse_t04_basename:   s   r/   dirpathc                 C  s^   t t}t| D ]#}tj| |}tj|sq	t|}|d u r"q	|\}}||| |< q	|S N)r   dictoslistdirpathjoinisfiler/   )r0   outr%   r   rprefixr.   r   r   r   scan_dirF   s   r;   dirpathsIterable[str]c                 C  sN   t t}| D ]}t|}| D ]\}}| D ]
\}}||| |< qqq|S r1   )r   r2   r;   items)r<   mergeddoner.   r   prer%   r   r   r   	scan_dirsT   s   rC   root	List[str]c                 C  sd   t j| sg S g }tt | D ]}|drqt j| |}t j|r/|t j| q|S )zv
    All immediate subdirectories of ``root`` (not recursive), sorted by name.
    Skips names starting with ".".
    .)	r3   r5   isdirr   r4   
startswithr6   appendabspath)rD   r8   r%   r   r   r   r   discover_subdirectories^   s   
rK   /DefaultDict[Tuple[Prefix, Timestamp], Set[str]]c           	      C  sz   t t}| D ]4}tj|}t|D ]&}tj||}tj|s#qt|}|du r,q|\}}|||f 	| qq|S )z=(prefix, timestamp) -> which folder basenames have that file.N)
r   setr3   r5   basenamer4   r6   r7   r/   add)	r<   r8   r@   br%   r   r9   r:   r.   r   r   r   where_present_keyo   s   	rQ   boolc                   C  s   t tj o
dtjvS )NNO_COLOR)rR   sysstdoutisattyr3   environr   r   r   r   _stdout_supports_ansi   s   rX   Ftitle
str | Noneshow_all_prefixesNonec                   s  t  t} rs'ttjtj odtjv d}|jt	ddd d S t
 }|r/tjntj}ttj| dd}t|rBt	|nd dd	dd
d	|dd
dd
}|jt	dddd D ]}	|jt|	ddd q[|r||jt	|rud| dndddd t D ]?}
d}t|
g}D ]}	|	 |
 v }||rdnd |r|d7 }q|r||kr|rdnd| d| }|| |j|  qt }t fdd D }| d|dkrdnd }|  || td| d | d!| d"tjdd# d S )$NrS   )r   no_colorz*(No matching .T04 files.)*dim)styleT)r   r]   	soft_wrapleftboldF)r   r   )
rY   title_justifytitle_styleshow_header
show_linesheader_styler	   padding	highlight	show_edgezTimestamp (12 chr)middle)justifyverticalcenterzAll ?zAll?r   yesu   —r   zno /c                 3  s,    | ] t  fd dD rdV  qdS )c                 3  s    | ]	}|  v V  qd S r1   r   )r   r   )r   tr   r   	<genexpr>   s    z(print_table.<locals>.<genexpr>.<genexpr>r   N)all)r   r   prefixes)rr   r   rs      s   * zprint_table.<locals>.<genexpr>z prefixesr   z
Count: z timestamps, z
 with all z.
)r   flush)r    r+   r
   rT   stderrrV   r3   rW   printr   rX   r	   ROUNDEDASCIIrU   r   
add_columnr$   r   r#   rI   add_rowsum)r   rY   r[   n_peuse_ansi	box_styleconsoletabler!   r.   ncellsyallnn_tsfulln_wordr   ru   r   print_table   sp   $
 


r   intc                  C  s  t jt jt} tjdtjd}|jddddd |jdt	| d	d
 |jdddd |jdddddd |jdddd |
 }t jt j|j}|jrYdd |jD }nt|}|sktd| tjd dS |D ]}t j|std| tjd  dS qmt|}t|d|jd |jr|D ]}t|}t|dt j| d|jd q|jrt|}d d | D }	td!tjd |	std"tjd d&S td#t|	 tjd t|	D ]}
td$|
d%||
 tjd qd&S )'NzPrint .T04 timestamp alignment table(s) (12-char stamp before .T04); device columns are the basename prefix before that timestamp, auto-discovered.)descriptionformatter_classdirs*DIRu   Directories to scan. If omitted, every immediate subdirectory of --root is used (non-recursive, sorted by name; entries starting with “.” are skipped).)nargsmetavarhelpz--rootzPWhen DIR arguments are omitted, this directory is scanned for subfolders to use.)typedefaultr   z--per-folder
store_truez/Also print a separate table for each directory.)actionr   z--all4-columnz--all-prefixes-columnall_prefixes_columnzxAdd a column showing when every auto-discovered prefix is present. (--all4-column name kept for backward compatibility.))r   destr   z--duplicateszDReport (prefix, timestamp) keys that appear in more than one folder.c                 S  s    g | ]}t jt j|qS r   )r3   r5   rJ   
expanduser)r   r@   r   r   r   
<listcomp>        zmain.<locals>.<listcomp>zNo subdirectories found under: r   r   zNot a directory: zCombined: all unique timestamps)rY   r[   zFolder `z` onlyc                 S  s    g | ]\}}t |d kr|qS )r   )r+   )r   kr   r   r   r   r     r   z0## Same prefix+timestamp in more than one folderzCount: 0zCount:  z->r   )r3   r5   dirnamerJ   __file__argparseArgumentParserArgumentDefaultsHelpFormatteradd_argumentr#   
parse_argsr   rD   r   rK   rz   rT   ry   rG   rC   r   r   
per_folderr;   rN   
duplicatesrQ   r>   r+   r   )default_rootr   argsrD   r   r@   combinedrA   locbothkeyr   r   r   main   s   r   __main__)r   r   r   r   )r!   r"   r   r#   )r%   r#   r   r&   )r0   r#   r   r   )r<   r=   r   r   )rD   r#   r   rE   )r<   rE   r   rL   )r   rR   )NF)r   r   rY   rZ   r[   rR   r   r\   )r   r   )6__doc__
__future__r   r   r3   rT   collectionsr   typingr   r   r   r   r   r   r	   rich.consoler
   rich.markupr   
rich.tabler   ModuleNotFoundError_er%   _mrH   r5   r   rJ   r   _herer6   _reqrz   
executablery   
SystemExitr#   	Timestampr"   r2   r   r    r$   r/   r;   rC   rK   rQ   rX   r   r   __name__r   r   r   r   <module>   sf   	











DT
