#!/usr/bin/env python
import os, sys, glob
import subprocess
from datetime import datetime, timedelta
from gpsdate import mkdate, fmtdate, date2gpsw


__authors__ = ["Ming Chen"]
__license__ = "Public Domain"
__maintainer__ = "Ming Chen"
__email__ = "ming.chen@noaa.gov"
__date__  = "April 22, 2025"

'''
#####################################################################
# 
# generate_bern_sessions.py
#
# Purpose:
# This python script is used to handle the BERNESE sessions.
##
# History:  
#       Created by: Ming Chen 2025/04/22
#                   ming.chen@noaa.gov
# 
# Usage: python .py start_datetime end_datetime
# the datetime in %Y-%m-%dT%H:%M:%S format
#
#
#####################################################################

'''

class UCARData():

    remote_home = 'https://data.cosmic.ucar.edu/gnss-ro'
    products = {
               'cosmic2': {
	          'nrt': {
	             'leoAtt': {'subdir':'nrt/level1a'},'podCrx': {'subdir':'nrt/level1a'},
	             'conPhs': {'subdir':'nrt/level1b'},'leoOrb': {'subdir':'nrt/level1b'},
	             'atmPrf': {'subdir':'nrt/level2'},'wetPf2b': {'subdir':'nrt/level2'},
	             'trgLv0': {'subdir':'nrt/level0'},},
	          'rapid': {
	             'conPhs': {'subdir':'rapid/level1b'},'podTc2': {'subdir':'rapid/level1b'},
	             'scnLv2f': {'subdir':'rapid/level2'}, }
		},
		   
               'spire':{
                  'nrt': {
	             'leoAtt': {'subdir':'noaa/nrt/level1a'},'podCrx': {'subdir':'noaa/nrt/level1a'},
	             'opnGns': {'subdir':'noaa/nrt/level1a'},'conPhs': {'subdir':'noaa/nrt/level1b'},
	             'leoOrb': {'subdir':'noaa/nrt/level1b'},
	             'podTec': {'subdir':'noaa/nrt/level1b'},
	             'atmPrf': {'subdir':'noaa/nrt/level2'}, 'wetPf2': {'subdir':'noaa/nrt/level2'}, }
               },

               'metopb': {
                  'postProc': {
	             'leoAtt': {'subdir':'postProc/level1a'},'podCrx': {'subdir':'postProc/level1a'},
	             'conGps': {'subdir':'postProc/level1a'},
	             'atmPhs': {'subdir':'postProc/level1b'},'leoOrb': {'subdir':'postProc/level1b'},
	             'leoClk': {'subdir':'postProc/level1b'},'podTec': {'subdir':'postProc/level1b'},
	             'atmPrf': {'subdir':'postProc/level2'},'wetPf2': {'subdir':'postProc/level2'},}
                },

               'metopc': {
                  'postProc': {
	             'leoAtt': {'subdir':'postProc/level1a'},'podCrx': {'subdir':'postProc/level1a'},
	             'conGps': {'subdir':'postProc/level1a'},
	             'atmPhs': {'subdir':'postProc/level1b'},'leoOrb': {'subdir':'postProc/level1b'},
	             'leoClk': {'subdir':'postProc/level1b'},'podTec': {'subdir':'postProc/level1b'},
	             'atmPrf': {'subdir':'postProc/level2'}, 'wetPf2': {'subdir':'postProc/level2'},}
                },
    }


    def __init__(self, mission):
      # Check if required environment variables are set
      self.podgen_home = os.getenv('podgen_home')
      self.utils_home  = os.getenv('utils_home')
      self.local_home  = os.getenv('ucar_data')
 
      if not self.podgen_home:
         print("env is not set up, source the set_env.bash file first ..")
         sys.exit(1)
      self.mission  = mission

    @staticmethod
    def valid_product(mission, prod, release,):
        valid = False
        if mission in UCARData.products: 
           if release in UCARData.products[mission]: 
              if prod in UCARData.products[mission][release]: 
                   valid = True
        else:
           print(f"mission {mission}  release {release} prod {prod} is not valid ....")
        return valid

    def remote_file(self, prod, release, pdate):
        subdir = UCARData.products[self.mission][release][prod]['subdir']
        yyyy = pdate.strftime('%Y') ; doy = pdate.strftime('%j')
        remote_path = f"{UCARData.remote_home}/{self.mission}/{subdir}/{yyyy}/{doy}"
        fn = f"{prod}_{release}_{yyyy}_{doy}.tar.gz"
        fpath = f"{remote_path}/{fn}"
        return fpath

    def local_filepath(self, prod,  pdate):
        yyyy = pdate.strftime('%Y') ; doy = pdate.strftime('%j')
        local_path = f"{self.local_home}/{self.mission}/{prod}/{yyyy}/{doy}"
        return local_path

    def local_filename(self, prod, pdate):
        yyyy = pdate.strftime('%Y') ; doy = pdate.strftime('%j')
        filename = f"{prod}_{yyyy}_{doy}.tar.gz"
        return filename

    def download(self, prod, pdate, release=None):
        # Download files	 
        if release is None:
           releases = UCARData.products[self.mission].keys()
           release = list(releases)[0]
        if not UCARData.valid_product(self.mission, prod, release):
           sys.exit(1)


        remote_path = self.remote_file(prod, release, pdate)
        print(f"Remote URL: {remote_path}")
        local_path = self.local_filepath(prod, pdate)
        local_file = self.local_filename(prod, pdate)
        local_file = f"{local_path}/{local_file}"
        print(f"Local Data  File: {local_file}")
        if os.path.exists(local_file):
              print(f"{local_file} already exists ...")
              

        if not os.path.exists(local_path):
              os.makedirs(local_path)

        cmd = f"wget -q {remote_path} -O {local_file}"
        print(cmd)
        subprocess.run(cmd, shell=True)

        # Check if the file was downloaded successfully
        if os.path.exists(local_file) and os.path.getsize(local_file) == 0:
           print(f"download failed ... {remote_path}")
           os.remove(local_file)
        if not os.path.exists(local_file):
           print(f"File download failed ...  {local_file}")
        else:  
           cmd = f"tar zxvf {local_file} -C {local_path} && rm -f {local_file}"
           print(cmd)
           subprocess.run(cmd, shell=True)

def local_ucar_filelist(mission:str, product:str, pdatestr:str, svn=None, ant=None):

   release = 'postProc'if 'metop' in mission else 'nrt'
   pdate = mkdate(pdatestr)
   if not UCARData.valid_product(mission, product, release):
      sys.exit(1)
  
   ucar = UCARData(mission)
   
   yyyy = pdate.strftime('%Y') ; doy = pdate.strftime('%j')
   local_path = ucar.local_filepath(product, pdate)
   filename = f"{product}_{yyyy}.{doy}"
   if svn != None: filename = f"{product}_{yyyy}.{doy}.{svn}"
   if svn != None and ant != None: filename = f"{product}_{yyyy}.{doy}.{svn}.*.{ant}"
   print(f"local ucar data home: {local_path}")

   filelist = []
   filelist = glob.glob( f"{local_path}/{filename}*" )
   return filelist

def wget_ucar_gnssro(mission:str, product:str, pdatestr:str):

   release = 'postProc'if 'metop' in mission else 'nrt'
   pdate = mkdate(pdatestr)
   if not UCARData.valid_product(mission, product, release):
      sys.exit(1)
  
   ucar = UCARData(mission)
   print(f"remote ucar url: {ucar.remote_home}")
   print(f"local ucar data home: {ucar.local_home}")
   print(f"product-date: {pdate.strftime('%Y-%m-%d')}")

   # Loop over dates
   datestr = pdate.strftime("%Y%m%d")
   gpswd = date2gpsw(datestr)
   gweek = gpswd[:4]
   gday = gpswd[4:]
   print(f"cdate, GWEEK, GDAY: {pdate.strftime('%Y%m%d')} {gweek} {gday} {gpswd} ")
   ucar.download(product, pdate)
 
if __name__ == "__main__":
   import argparse

   parser = argparse.ArgumentParser(description='wget ucar data')
   parser.add_argument("-v","--verbose", action='store_true',  help="print info for debug")
   parser.add_argument("mission", type=str,  help="cosmic2, spire ")
   parser.add_argument("product", type=str,  help="producte.g., leoAtt, podCrx, leoOrb")
   parser.add_argument("prod_date", type=str,  help="product date in yyyymmdd yyyydoy ")
   #parser.add_argument("-r","--release", type=str, default='nrt', help="nrt, postProc")

   args = parser.parse_args()
   mission, prod = args.mission, args.product
   pdate = args.prod_date  
   #wget_ucar_gnssro(mission, prod, pdate)
   #flist = local_ucar_filelist(mission, prod, pdate, svn='006')
   #print(flist)
