#!/usr/bin/env python
"""

 Run the single-diff C/N0, code-phase, and carrier-phase function

   Interface to cal_single_diff() in ProcessResults.py

 Example:
  ./run_single_diff.py /home/ddelore/DataDir/RX6-2209

  Optional arguments:
    -c, --cycle_slip  Run the cycle-slip analysis for ant#0 and ant#1
    -p, --plot_png    Store PNG files to /mnt/data_drive/ddelore/Images
    --max_svs         Max no. of satellites [defaults to Inf]
    --scenario        Test scenario ID [defaults to N/A]
    --combos          Constellation, band, signal combination

  How to prepare your environment to run this function:
    1. copy ProcessResults.py from AntiJamTest/server_control_main
       to pythonTools/mutils/
    2. add the following line to pythonTools/mutils/__init__.py
         from .ProcessResults import *
    3. minimum required changes to your copy of ProcessResults.py
         comment out:
           #from ProcessResultsStorage import init_table, add_data_to_db
           #import ProcessResultsCalculations
         delete:
           elif band == RTConst.dRec27L5Band:
               wave_frequency = GnssConst.L5_FREQ
         change the interface to:
           def cal_single_diff(d, k, rec, sy, freq, sv_range, track,
                               intervals=[[]], union_intervals=False,
                               plot_png=False, plot_time_offset=0,
                               out_path='./', max_svs=math.inf):
         before "for sv in sv_range:" add:
           sv_ctr = 0
         after "if len(ant0[0])>0 and len(ant1[0])>0:" add:
           sv_ctr += 1
           if sv_ctr > max_svs:
               break
"""


import os
import math
import argparse
import numpy as np
from mutils import vd2arr
from mutils import RTConst
from mutils import default_combo, get_band_name
from mutils import get_sys_name_and_sv_range
from mutils import cal_single_diff
from mutils import cycle_slip_analysis


def plt_single_diff(args):

    path_name = args.path_name
    scenario = args.scenario
    combos = args.combos

    save_dir = '/home/ddelore/Images/delete_me'
    for p in path_name.split('/'):
        if p.startswith('RX'):
            save_dir = os.path.join('/home/ddelore/Images', p)

    if not path_name.endswith('.T04'):
        path_name = os.path.join(path_name, '*.T04')

    if scenario == 'N/A':
        interval = [0, 604800]
    elif scenario == '2b':
        interval = [432379, 433529]
    elif scenario == '3b':
        interval = [432365, 433555]
    elif scenario == '3c':
        interval = [432365, 433555]
    elif scenario == '5b':
        interval = [432379, 433544]
    else:
        interval = [432505, 432655]

    # Load T04 file(s)
    rec = '-d35:19'
    d, k = vd2arr(path_name, rec)

    # Get time range
    tow = d[:, k['TIME']]
    [tow_start, tow_end] = [min(tow), max(tow)]

    # Build processing combinations
    combos_all = []
    if 'a' in args.combos:
        combos_all.append( default_combo('GPS',
                                         RTConst.RT_SatType_GPS,
                                         RTConst.dRec27L1Band,
                                         [RTConst.dRec27Track_CA]) )
    if 'b' in args.combos:
        combos_all.append( default_combo('GPS',
                                         RTConst.RT_SatType_GPS,
                                         RTConst.dRec27L2Band,
                                         [RTConst.dRec27Track_CMCL]) )
    if 'c' in args.combos:
        combos_all.append( default_combo('GPS',
                                         RTConst.RT_SatType_GPS,
                                         RTConst.dRec27L5E5ABand,
                                         [RTConst.dRec27Track_IQ]) )
    if 'd' in args.combos:
        combos_all.append( default_combo('GPS',
                                         RTConst.RT_SatType_GPS,
                                         RTConst.dRec27L2Band,
                                         [RTConst.dRec27Track_E]) )
    if 'e' in args.combos:
        combos_all.append( default_combo('GLN',
                                         RTConst.RT_SatType_GLONASS,
                                         RTConst.dRec27L1Band,
                                         [RTConst.dRec27Track_CA]) )
    if 'f' in args.combos:
        combos_all.append( default_combo('Gal',
                                         RTConst.RT_SatType_GALILEO,
                                         RTConst.dRec27L1Band,
                                         [RTConst.dRec27Track_BOC_1_1_DP_MBOC]) )
    if 'g' in args.combos:
        combos_all.append( default_combo('BDS',
                                         RTConst.RT_SatType_BEIDOU_B1GEOPhs,
                                         RTConst.dRec27B1Band,
                                         [RTConst.dRec27Track_B1]) )
    if 'h' in args.combos:
        combos_all.append( default_combo('Gal',
                                         RTConst.RT_SatType_GALILEO,
                                         RTConst.dRec27E5ABCentreBand,
                                         [RTConst.dRec27Track_AltBOCCompPD]) )

    for combo in combos_all:
        print("Input combo:", combo)
        sat_type, band, track = combo.sat_type, combo.band, combo.track
        sat_sys_name = combo.sat_sys_name
        band_name = get_band_name(band)
        _, sv_range = get_sys_name_and_sv_range(sat_type)

        # Calculate single-diff C/N0, code-phase, and carrier-phase
        #
        #   Input:
        #       d = 2D array loaded from .T04 files
        #       k = key dictionary from .T04 files
        #       rec = string, eg. '-d27' or '-d35:19'
        #       sy = satellite type
        #       freq = block type (frequency)
        #       sv_range = list of satellite IDs, eg. [1,2,3,..32]
        #       track = list of track/signal type, eg. [0]
        #       intervals = eg. [[]] or [[t0, t1],[t2,t3], ...]
        #       union_intervals = True/False, union intervals or not
        #       jam_start
        #       jam_end
        #       plot_png = True/False
        #       plot_time_offset = offset time in plot, unit [sec]
        #       out_path = path to save image(s)
        #       max_svs = max number of SVs to process
        #
        stat_i = cal_single_diff(d, k, rec, sat_type, band, sv_range, track,
                                 intervals=[[0, 604800]], plot_png=args.plot_png,
                                 jam_start=432505, jam_end=432655,
                                 out_path=save_dir, max_svs=args.max_svs)

        if args.cycle_slip:
            #
            # Calculate cycle slips for GPS L1-C/A and GLO G1C
            #
            #   Input:
            #       d = 2D array loaded from .T04 files
            #       k = key dictionary from .T04 files
            #       rec = string, eg. '-d27' or '-d35:19'
            #       sy = satellite type
            #       freq = block type (frequency)
            #       sv_range = list of satellite IDs, eg. [1,2,3,..32]
            #       track = list of track/signal type, eg. [0]
            #       intervals = eg. [[]] or [[t0, t1],[t2,t3], ...]
            #       plot_png = True/False
            #       plot_time_offset = offset time in plot, unit [sec]
            #       out_path = path to save image(s)
            #       max_svs = max number of SVs to process
            #
            ant_cs0, ant_cs1 = \
                cycle_slip_analysis(d, k, rec, sat_type, band, sv_range, track,
                                    plot_png=args.plot_png, out_path=save_dir)

            print('Antenna #0 cycle slips = {}'.format(int(sum(ant_cs0)[4])))
            print('Antenna #1 cycle slips = {}'.format(int(sum(ant_cs1)[4])))


if __name__ == '__main__':
    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter,
                                     description=__doc__)

    parser.add_argument('path_name', help='name of or path to your T04 file(s)')
    parser.add_argument('-c', '--cycle_slip', action='store_true',
                        help='run the cycle-slip analysis for ant#0 and ant#1')
    parser.add_argument('-p', '--plot_png', action='store_true',
                        help='store PNG files to /mnt/data_drive/ddelore/Images')
    parser.add_argument('--max_svs', type=float, default=math.inf,
                        help='max no. of satellites [defaults to Inf]')
    parser.add_argument('--scenario', default='N/A',
                        help='test scenario ID [defaults to N/A]')
    parser.add_argument('--combos', default='abcdefgh',
                        help='constellation, band, signal combination')


    args = parser.parse_args()
    plt_single_diff(args)

