#!/usr/bin/python3

"""
@file
@ingroup trs_common_trsutils
@copyright ESO - European Southern Observatory
@author C. Soenke

@brief Time conversion application

"""

import argparse
import datetime
import textwrap

from astropy.time import Time
#from astropy.utils.data import clear_download_cache

from trslib.time import astropy_utils
from trslib.time import converter


def parse_args():
    """
    Parse command line arguments
    """

    description = textwrap.dedent('''\
        Tool to print/convert time
        
        Reference data:
        ---------------
        The underlying Astropy library requires earth rotation (IERS A) and leapsecond data
        to carry out the conversions. The related files are located in the following order:
        - when environment variable TINFO_DATA is defined, the files are expected under
          $TINFO_DATA/CURRENT. If they are not found, loading from $TINFO_DATA/DEFAULT is
          attempted. If this fails, the Astropy defaults will be used which may result in
          automatic download from the internet depending on the age of the defaults or the
          Astropy download cache.
        - when environment variable TINFO_DATA is not defined, path /var/lib/elt/trs/tinfo
          is assumed for TINFO_DATA and the same procedure as above applies.
        - when --iersfile or leapsecfile are specified, those files will be used. If only one
          is specified, the above mechanisms apply for the other.

        The specified paths can either be local filesystem paths or URLs (http://, https://).

        To define environment variable TINFO_DATA and thus avoid automatic download from the
        internet (e.g. in the ECM), use:

        $ export TINFO_DATA=http://trshks.ecm.hq.eso.org/TRS/tinfo-data
        
        Examples:
        ---------
        
        Print current time with all available conversions:
        $ trsConvert
        
        Print specified UTC time with all available conversions:
        $ trsConvert --time 2025-11-18T14:56:08.18 --infmt utc_iso
        
        
        Print specified mjd time with all available conversions:
        $ trsConvert --time 60997.62231700125 --infmt mjd
        
        ''')

    parser = argparse.ArgumentParser(description=description,
                                     formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('--time', help='Time in the format specified by --infmt argument',
                        action='store', dest='t_usr')
    parser.add_argument('--infmt', help='utc_iso/tai_iso in format yyyy-mm-ddThh:mm:ss.d,\
                        unix_seconds/tai_seconds in seconds (double), tai_hex and mjd in days\
                        (double)', action='store', dest='infmt',
                        choices=['utc_iso', 'tai_iso', 'unix_seconds', 'tai_seconds', 'tai_hex',
                                 'mjd'])
    parser.add_argument('--printleap', dest='printleap', action='store_const',
                        const=True, default=False,
                        help='Print leap seconds list (overrides other args)')
    parser.add_argument('--iersfile',
                        help='Path or URL to IERS_A data file (IERS_finals2000A.all) - \
                        deactivates automatic download',
                        action='store', default=None)
    parser.add_argument('--leapsecfile',
                        help='Path or URL to Leap_Second.dat file - \
                        deactivates automatic download',
                        action='store', default=None)
    return parser.parse_args()


def print_leap_seconds_list():
    """
    Print the list of leap-seconds until today
    """

    #print for january 1st and july 1st of every year
    dt = datetime.datetime.now()
    times = []
    for year in range(1960, dt.year + 1):
        times.append('{}-01-01'.format(year))
        times.append('{}-07-01'.format(year))

    t_utc = Time(times, scale='utc')
    t_tai = Time(times, scale='tai')
    dt = t_utc - t_tai

    print('Year   Jan 1st   July 1st')
    print('-------------------------')
    for n in range(0, len(times)//2):
        print('%s:  %6.3f     %6.3f' % (times[n*2][0:4], dt[n*2].sec, dt[n*2+1].sec))


def main():
    """trsConvert main"""

    # Clear Astropy download cache (for testing)
    #clear_download_cache()

    args = parse_args()

    # Check if local IERS or leapsec file is specified
    iers = astropy_utils.AstropyIers()
    if args.iersfile is None:
        ret = iers.load_iers_a(max_age=None, try_load=True)
        if ret:
            print('Loaded current/default IERS A file')
        else:
            print('Using Astropy default IERS A data')
    else:
        iers.load_iers_a(filename=args.iersfile, max_age=None)
        print('Using user specified IERS A file')

    if args.leapsecfile is None:
        ret = iers.load_leapsec(max_age=None, try_load=True)
        if ret:
            print('Loaded current/default leapsec file')
        else:
            print('Using Astropy default leapsec data')
    else:
        iers.load_leapsec(filename=args.leapsecfile, max_age=None)
        print('Using user specified lepasec file')

    # Print leap seconds list
    if args.printleap:
        print_leap_seconds_list()
        return

    # Do conversion
    if args.t_usr is None:
        t = converter.TimeObj('now', None)
    else:
        t = converter.TimeObj(args.t_usr, args.infmt)

    print('UTC            : {}'.format(t.get_utc()))
    print('TAI            : {}'.format(t.get_tai()))
    print('UT1            : {}'.format(t.get_ut1()))
    print('Garching       : {}'.format(t.get_tz_time('Europe/Berlin')))
    print('Chile          : {}'.format(t.get_tz_time('Chile/Continental')))
    print('Unix (POSIX)   : {0:.8f}'.format(t.get_unix()))
    print('TAI (Epoch-70) : {0:.8f} ({1:})'.format(t.get_tai_seconds(),
                                                   t.double_to_hex(t.get_tai_seconds())))
    print('Sidereal (VLT) : {} (apparent), {} (mean)'.format(
        t.get_sidereal('VLT', 'apparent'), t.get_sidereal('VLT', 'mean')))
    print('Sidereal (ELT) : {} (apparent), {} (mean)'.format(
        t.get_sidereal('ELT', 'apparent'), t.get_sidereal('ELT', 'mean')))
    print('ERA (VLT)      : {}'.format(t.get_era('VLT')))
    print('ERA (ELT)      : {}'.format(t.get_era('ELT')))
    print('MJD            : {}'.format(t.get_mjd()))
    print('DUT1           : {0:.7f}'.format(t.get_dut1()))
    print('Leap seconds   : {0:.1f}'.format(t.get_leap_seconds()))
    print('Is leapsec     : {}'.format(t.is_leap_second()))


if __name__ == "__main__":
    main()
