#!/usr/bin/env python
import os, sys, glob, subprocess, shutil
from datetime import datetime, timedelta
import re, string
import numpy as np
from satellite_info import env_paths, sat_ant_info
from ucar2umd_rnx import UCAR2UMD_RNX, ucar_crx2rnx
from utility import str2date, leofile_time_range
from ucar_gnssro_data import local_ucar_filelist


'''
#####################################################################
# 
# rt_file_reproc.py
#
# Purpose:
#
# This Python script script identifies missing RT SP3 files
# resulting from failed BERNESE runs, and return the list 
# for the reprocessing
#
# History:  
#       Created by: Ming Chen 2026/05/08
#                   ming.chen@noaa.gov
# 
#
#####################################################################

'''


def umdrepo_rnx_filelist(mission, satidx, antidx, sdate, **kwargs):      
    # Check if required environment variables are set

    umd_repo = kwargs.get('umd_repo','')
    satinfo = sat_ant_info(mission, satidx, antidx)
    if satinfo == None:return None
    satsvn =  satinfo['satsvn'] ; satname = satinfo['satname'] 
    antenna = satinfo['antsvn'] 
    if antenna == None: 
       print("error in antidx {}".format(antidx))
       return None
    year = sdate.strftime('%Y') 
    jday = sdate.strftime('%j')
    #rnxpath = os.path.join(umd_repo, mission,'level1a','podCrx', year,jday)
    #rnxpath = os.path.join(umd_repo, mission,'v1.26', 'level1a','podCrx', year,jday)
    #rnxpath = os.path.join(umd_repo, mission,'v1.26_rt_simulator', 'level1a','podCrx', year,jday)
    rnxpath = os.path.join(umd_repo, year,jday)
    fnames = 'podCrx_{}.{}*.{}.{}.'.format( year,jday,satsvn, antenna)

    flist = glob.glob(rnxpath+'/'+fnames+'*_rnx', recursive=False)
    return flist

def leoOrb_filepath(mission, pdate):
    archdir  = os.getenv('archive_home')
    year = pdate.strftime('%Y') ; jday = pdate.strftime('%j')
    yday = f'{year}.{jday}' 
    leoOrb_Path =  os.path.join(archdir, mission, 'LEOPOD', 'leoOrb', yday)
    
    return leoOrb_Path


def leosp3_filename(mission, satidx, antidx,  ftime):
    satinfo = sat_ant_info(mission, satidx=satidx, antidx=antidx)
    if satinfo == None:return None
    satsvn =  satinfo['satsvn'] ; satname = satinfo['satname'] 
    antenna = satinfo['antsvn'] ; bernid =  satinfo['bernid'] 
    if antenna == None: 
       print("error in antidx {}".format(antidx))
       return None
    ttag = ftime.strftime('%Y%m%dT%H%M%S')
    sp3file = f"leoOrb_{ttag}_{bernid}.SP3"
 
    return sp3file

def split_rnx_filename(filename):
    #podCrx_2026.120.16.35.005.02.CUIABA_rnx
    pattern = r"podCrx_(\d{4})\.(\d{3})\.(\d{2})\.(\d{2})\.(\d{3})\.(\d{2})\..+_rnx"

    match = re.match(pattern, filename)
    if match:
       year, doy, hour, minute, sat, ant = match.groups()
       dt = timedelta(days=int(doy) - 1)
       ftime = datetime(
                int(year), 1, 1, int(hour), int(minute),0,0) + dt

       return (ftime, int(sat), int(ant))
    else:
       return (None,None,None)

def missed_leoorb_list(mission, satidx, antidx, tstart, tend,   **kwargs):      

    alpha=list(string.ascii_uppercase)
    verbose = kwargs.get('verbose') 
    umd_repo = kwargs.get('umd_repo','')
    grace_hours = kwargs.get('grace_hours',0)

    satinfo = sat_ant_info(mission, satidx, antidx)
    if satinfo == None:return None
    satsvn =  satinfo['satsvn'] ; satname = satinfo['satname'] 
    antenna = satinfo['antsvn'] 

    dt = timedelta(hours=grace_hours)
    #ndays = (tend - tstart + dt + dt).days
    sdate = (tstart - dt).strftime('%Y%m%d') ; sdate = datetime.strptime(sdate,'%Y%m%d')
    edate = (tend + dt).strftime('%Y%m%d') ; edate = datetime.strptime(edate,'%Y%m%d')


    filelist =[]
    while sdate <= edate:
       year = sdate.strftime('%Y') 
       jday = sdate.strftime('%j')
       yday = f'{year}.{jday}'
       datestr = sdate.strftime('%Y%m%d')
       if umd_repo.strip():
          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

    flist=[]
    for f in filelist:
        _, basename = os.path.split(os.path.abspath(f))
        ftime, satidx, antidx = split_rnx_filename(basename)
        if ftime:
            timetag = ftime.strftime('%Y%m%dT%H:%M:%S')
            if ftime < tstart or ftime > tend: continue
            #print(timetag, satidx, antidx)
            leosp3_path = leoOrb_filepath(mission, ftime)
            leosp3_fname = leosp3_filename(mission, satidx, antidx,  ftime)
            leosp3 = os.path.join(leosp3_path,leosp3_fname)
            if not os.path.isfile(leosp3):
               flist.append(f"{satidx:02d}_{antidx:02d}={timetag}")
               #print(f) ; print(leosp3)
    return flist

def check_missed_leoorb(mission, tstart, tend, satidx=None, antidx=None, **kwargs):      
    umd_repo = kwargs.get('umd_repo','')
    leoinfo = sat_ant_info(mission)
    nsat = leoinfo['nsats'] ; nant = leoinfo['nant']
    leosats = [i+1 for i in range(nsat)]
    leoants = [i+1 for i in range(nant)]
    leoants = [1]
    if satidx:
       if isinstance(satidx, list) and len(satidx) >0:
          leosats = satidx
       else:
         if satidx > 0: leosats = [satidx]
    if antidx:
       if isinstance(antidx, list) and len(antidx) >0:
          leoants = antidx
       else:
         if antidx > 0: leoants = [antidx]

    mlist = []
    for satidx in leosats:
       for antidx in leoants:
           flist=missed_leoorb_list(mission, satidx, antidx, tstart, tend, umd_repo=umd_repo)
           if flist: mlist.extend(flist)
    #print(mlist)
    return mlist
# ----------------------------------------------------------------------
# Argument parsing
# ----------------------------------------------------------------------
def parse_args():
    import argparse
    parser = argparse.ArgumentParser(
        description="Main Program arguments"
    )
   
    parser.add_argument("-t","--datetime", help = "%Y-%m-%dT%H:%M:%S")
    parser.add_argument("--window-minutes", type=float, default=60.0, help="Override minutes from YAML")
    parser.add_argument("--grace-minutes", type=float, default=0.0, help="Override grace from YAML")
    parser.add_argument("--workers", type=int, default=4)
    parser.add_argument("--dry-run", action="store_true")
    parser.add_argument("mission", type=str,  help="cosmic1 or cosmic2")
    parser.add_argument("--satidx", type=int, default=-1, help="cosmic2 satidx 1-6")
    parser.add_argument("--antidx", type=int, default=-1,  help="cosmic2 antenna index 1-2")
    parser.add_argument("--umd-repo",  type=str, default='', help="path to umd local ucar data repository"  )
    parser.add_argument("-ucar","--ucar-data-home",type=str,  help="Local UCAR data home path "  )
    parser.add_argument("-umd","--umd-data-home",  type=str,  help="UMD data home path "  )
    parser.add_argument("-util","--utility-home",  type=str,  help="POD utility home path "  )
    parser.add_argument("-v","--verbose", action='store_true',  help="print info for debug")


    return parser.parse_args()

    
if __name__ == "__main__":
    # example 
    # python ucar2umd_rnx_rt.py cosmic2 2 2 -t "2026-04-05T03:00:00" --umd-repo '/ROSDC_data3/xinjiaz/data_GPSRO/UCAR_unpack_STAR'

    args = parse_args()
    ddt = datetime.strptime(args.datetime, "%Y-%m-%dT%H:%M:%S")

    # Time window
    window_minutes = args.window_minutes
    grace_minutes = args.grace_minutes 
    umd_repo = args.umd_repo
    umd_repo = '/ROSDC_data3/xinjiaz/data_GPSRO/UCAR_unpack_STAR/cosmic2/v1.26_rt_simulator/level1a/podCrx'
    total_minutes = window_minutes + grace_minutes
    if total_minutes < 0:
       t_start = ddt + timedelta(minutes=total_minutes)
       t_end   = ddt
    else:
       t_start = ddt ; t_end   = ddt + timedelta(minutes=total_minutes)

    tstart = t_start.strftime("%Y%m%dT%H%M%S")
    tend = t_end.strftime("%Y%m%dT%H%M%S")
    mission = args.mission ; satidx = args.satidx ; antidx = args.antidx
    print(tstart, tend)
    
    verbose = args.verbose

    print(satidx, tstart, tend)
    check_missed_leoorb(mission, t_start,t_end, satidx=satidx, antidx=antidx, verbose=verbose, umd_repo =umd_repo)
