#!/bin/env python 
import argparse
import os,sys, shutil
from ucar2umd_rnx_rt import umdrepo_rnx_filelist, extract_pdate_from_umdrnx_filepath
from datetime import datetime, timedelta, timezone
import re, string
from utility import  leofile_time_range, leofile_time_range_from_data
import time
from pathlib import Path

__authors__ = ["Ming Chen"]
__license__ = "Public Domain"
__maintainer__ = "Ming Chen"
__email__ = "ming.chen@noaa.gov"
__date__  = "May 08, 2026"

'''
#####################################################################
# 
# rt_file_monitor.py
#
# Purpose:
# This Python script tracks the latest available COSMIC-2 attitude
# and RINEX files to support real-time processing workflows.
#
# History:  
#       Created by: Ming Chen 2026/05/08
#                   ming.chen@noaa.gov
# 
#
#####################################################################

'''


def latest_satant_dict(mission, satidx, antidx, now_utc, **kwargs):
   
    umd_repo = kwargs.get('umd_repo','')
    #print(umd_repo)

    grace_hours = 3
    dt = timedelta(hours=grace_hours)
    
    sdate = (now_utc - dt).strftime('%Y%m%d') ; sdate = datetime.strptime(sdate,'%Y%m%d')
    edate = (now_utc).strftime('%Y%m%d') ; edate = datetime.strptime(edate,'%Y%m%d')

    filelist =[]
    while sdate <= edate:
       #print(mission, satidx, antidx, sdate, umd_repo)
       flist = umdrepo_rnx_filelist(mission, satidx, antidx, sdate, umd_repo = umd_repo)
       filelist += flist
       sdate = sdate + timedelta(days=1)  

    if len(filelist) < 1: return None

    flatest = sorted(filelist)[-1]
    flatest2 = sorted(filelist)[-2]
    #flatest = sorted(filelist,key=os.path.getmtime)[-1]
    #flatest2 = sorted(filelist,key=os.path.getmtime)[-2]
    rr=leofile_time_range(flatest)
    if  rr[1] != None :
        reftime =  datetime.strptime(rr[1],'%Y%m%dT%H:%M:%S.%f')
    fpattern = r'(\d{4}\.\d{3}\.\d{2}\.\d{2})\.(\d{3})\.(\d{2})'
    m = re.search(fpattern, flatest)
    latest_time, sat, ant = m.groups()
    current_time = datetime.strptime(latest_time, "%Y.%j.%H.%M")
    tmd = (current_time - reftime).total_seconds()
    m_time = os.path.getmtime(flatest) ; now = time.time()
    seconds_since_mod = now - m_time

    if seconds_since_mod < 60:
       print(f'{flatest}: short file lifetime  {seconds_since_mod} seconds....')
       print(current_time,reftime,tmd)
       m = re.search(fpattern, flatest2)
       latest_time, sat, ant = m.groups()
       current_time = datetime.strptime(latest_time, "%Y.%j.%H.%M")
 
    #print(current_time, sat, ant)
    return current_time


def parse_satant_file(filepath):
    result = {}
    # single regex for the whole line
    pattern = re.compile(
        r'sat:\s*(\d+)\s+ant:\s*(\d+)\s+start_time:\s*"([^"]*)"\s+end_time:\s*"([^"]*)"\s+([01])'
    )

    with open(filepath, "r") as f:
        for line in f:
            match = pattern.search(line)
            if match:
                sat, ant, start_time, end_time, status = match.groups()
                key = f"{sat}_{ant}"

                result[key] = {
                    "sat": sat,
                    "ant": ant,
                    "start_time": start_time,
                    "end_time": end_time,
                    "status": status
                }

    return result



def dump_satant_dict(data_dict, filepath):
    with open(filepath, "w") as f:
        for key, entry in data_dict.items():
            line = (
                f'sat:{entry["sat"]} '
                f'ant:{entry["ant"]} '
                f'start_time: "{entry["start_time"]}" '
                f'end_time: "{entry["end_time"]}" '
                f'{entry["status"]}\n'
            )
            f.write(line)

def update_rt_satant_dict(mission, satant_list_file,   **kwargs):

    umd_repo_default = "/mnt/uvol0/xinjia.zhou/data_GPSRO/cosmic2_nccf/level1a/podCrx"
    umd_repo = kwargs.get('umd_repo',umd_repo_default)
    now_utc = datetime.now(timezone.utc)
    ctime = now_utc 
    default_sliding_minutes = 60
    
    if not os.path.exists(satant_list_file):
       shutil.copy('cosmic2_satant.template', satant_list_file)

    satant_dict = parse_satant_file(satant_list_file)
    #print( satant_dict)
    satant_dict_new = {}
 
    sats = [1, 2, 4, 5, 6]; ants = [1, 2]
    for satidx in sats:
       for antidx in ants:
         current_time = latest_satant_dict(mission, satidx, antidx, ctime, umd_repo=umd_repo)
   
         if current_time is None: continue
     
         latest_time = current_time.strftime("%Y%m%dT%H:%M:00")
         default_start_time = current_time - timedelta(minutes=default_sliding_minutes)
         default_start_time = default_start_time.strftime("%Y%m%dT%H:%M:00")
         mykey = f'{satidx:02d}_{antidx:02d}'

         satant_dict_new[mykey] = {}
         satant_dict_new[mykey]['sat'] = f'{satidx:02d}'
         satant_dict_new[mykey]['ant'] = f'{antidx:02d}'

         if mykey in satant_dict:
            if satant_dict[mykey]['end_time'] != latest_time:
               satant_dict_new[mykey]['start_time'] = satant_dict[mykey]['end_time'] \
	       if satant_dict[mykey]['end_time'] else  default_start_time
               satant_dict_new[mykey]['end_time'] = latest_time
               satant_dict_new[mykey]['status'] = 1
            else :
               satant_dict_new[mykey]['start_time'] = satant_dict[mykey]['start_time']
               satant_dict_new[mykey]['end_time'] = satant_dict[mykey]['end_time']
               satant_dict_new[mykey]['status'] = 0

         else:
            satant_dict_new[mykey]['start_time'] = default_start_time
            satant_dict_new[mykey]['end_time'] = latest_time
            satant_dict_new[mykey]['status'] = 1
    dump_satant_dict(satant_dict_new, satant_list_file)

    return satant_dict_new
 

def get_previous_filelist(filelist_fname):
   filelist = []
   with open(filelist_fname, 'r') as file:
      for line in file:
        # Strip whitespace/newlines and skip empty lines
        file_path_str = line.strip()
        if not file_path_str:
            continue
            
        # Convert to a Path object and get the parent directory
        file_path = Path(file_path_str)
        parent_directory = file_path.parent
        basename = file_path.name
        filelist.append(basename)

   return filelist

def get_current_filelist(mission, satidx, antidx, now_utc, **kwargs):
   
    umd_repo = kwargs.get('umd_repo','')
    pdate = kwargs.get('pdate',None)
    #print(umd_repo)
    
    sdate = (now_utc).strftime('%Y%m%d')  ; sdate = datetime.strptime(sdate,'%Y%m%d')
   
    flist = umdrepo_rnx_filelist(mission, satidx, antidx, sdate, umd_repo = umd_repo)

    if pdate != None:
       pflist = umdrepo_rnx_filelist(mission, satidx, antidx, pdate, umd_repo = umd_repo)
       filelist = pflist + flist
    else:
       filelist = flist
 
    if len(filelist) < 1: return None

    return filelist


def dump_current_filelist(flist, filepath):
    with open(filepath, "w") as f:
        for line in flist:
          f.write(line+"\n")


def update_rt_filelist(mission, satant_list_file,   **kwargs):

    umd_repo_default = "/mnt/uvol0/xinjia.zhou/data_GPSRO/cosmic2_nccf/level1a/podCrx"
    umd_repo = kwargs.get('umd_repo',umd_repo_default)
    now_utc = datetime.now(timezone.utc)
    ctime = now_utc 
    N_CPU =  12
    grace_hours = 3
    dt = timedelta(hours=grace_hours)    
    midnight = now_utc.replace(hour=0, minute=0, second=0, microsecond=0)
    minutes_today = (now_utc-midnight).total_seconds() / 60
    pdate =  None
    if minutes_today < grace_hours*60:
       pdate = (now_utc - dt).strftime('%Y%m%d') 
       pdate = datetime.strptime(pdate,'%Y%m%d')
    
    if not os.path.exists(satant_list_file):
       Path(satant_list_file).touch()

    previous_list = get_previous_filelist(satant_list_file)

    sats = [1, 2, 4, 5, 6]; ants = [1, 2]
    current_list = []
    for satidx in sats:
       for antidx in ants:
         flist = get_current_filelist(mission, satidx, antidx, ctime, umd_repo=umd_repo, pdate=pdate)

         if flist == None: continue
         flist = [ Path(f).name for f in flist ] 
         current_list.extend(flist)
    

    latest =  set(current_list) - set(previous_list)
    latest = sorted(latest, reverse=True)
    latest_flist = []
    n = len(latest)
    n = n if n < N_CPU else N_CPU
     
    current_list = sorted(current_list, reverse=True)
    latest = latest[0:n]
    for flatest in latest:
       fpattern = r'(\d{4}\.\d{3}\.\d{2}\.\d{2})\.(\d{3})\.(\d{2})'
       m = re.search(fpattern, flatest)
       latest_time, sat, ant = m.groups()
       current_time = datetime.strptime(latest_time, "%Y.%j.%H.%M")
       timetag = current_time.strftime('%Y%m%dT%H:%M:%S')
       satidx=int(sat) ;  antidx = int(ant)
       latest_flist.append(f"{satidx:02d}_{antidx:02d}={timetag}")
 
    dump_current_filelist(current_list, satant_list_file)
   
    return latest_flist
  
def main():
    mission = 'cosmic2'
    satant_list_file='rt_file.list'

    ctime = datetime.strptime("2026.194.19.00", "%Y.%j.%H.%M")
    umd_repo ='/data2/mchen36/POD_DATA/umd/cosmic2/podRnx'
    latest_flist=update_rt_filelist(mission, satant_list_file, umd_repo =umd_repo)
    print(latest_flist)
    satant_list_file='rt_run_satant.list'
    latest_dict = update_rt_satant_dict(mission, satant_list_file,umd_repo =umd_repo)
    print(latest_dict)
if __name__ == "__main__":
    main()

