#!/usr/bin/env python3
import pandas as pd
import os
import argparse
import sys
from datetime import datetime
import subprocess
import os
import matplotlib.pyplot as plt

import viewdat_cno_lib as vdl
import gutil



# ----------------------------------------------------
# Main
# ----------------------------------------------------
def main():
    total_start_time = datetime.now()

    parser = argparse.ArgumentParser(
            description='Process C/No (SNR).',
            formatter_class=argparse.ArgumentDefaultsHelpFormatter
            )
    parser.add_argument('-v', '--Verbose', action='count', default=0)
    parser.add_argument(
            "folder",
            help="Base folder for file I/O. Inputs are .T04. ",
            )
    parser.add_argument(
            "-A", "--antenna",
            type=int,
            default=0,
            choices=[0, 1],
            help="Antenna to use from the file (0=primary, 1=secondary)"
            )
    parser = gutil.common_args(parser)

    outp = parser.add_argument_group('output folder options')
    outp = gutil.folder_args(outp)

    vdp = parser.add_argument_group('viewdat')
    vdp = gutil.viewdat_args(vdp)

    debugp = parser.add_argument_group('debug options')
    debugp = gutil.debug_args(debugp, force=True)
    debugp.add_argument(
            "--dry-run",
            action='store_true',
            help="Don't do anything, just show what viewdat commands would be run." # noqa E501
    )

    args = parser.parse_args()

    index_path = os.path.join(args.folder, 'index.html')
    #for root, dirs, files in os.walk(args.folder):

    # ------------ File name mangling
    #fname_base = os.path.splitext(args.fname)[0] + f"_{args.antenna}"
    #fname_path = os.path.join(args.folder, args.fname)
    #fname_base = fname_base.replace('*', '')
    data_out_dir = os.path.join(args.folder, args.data_out_dir)
    fig_dir = os.path.join(args.folder, args.report_dir)
    #out_base = os.path.join(args.folder, args.data_out_dir, fname_base)
    #html_base = os.path.join(args.folder, args.report_dir, fname_base)

    os.makedirs(data_out_dir, exist_ok=True)
    #if args.plot or args.html:
    #    os.makedirs(os.path.join(args.folder, args.report_dir), exist_ok=True)

    viewdat = vdl.exe_name(args.viewdat)
    if viewdat is None:
        print('viewdat executable not found. Aborting')
        sys.exit()

    #meta = vdl.meta_read(fname_path, viewdat, args.antenna, True)

    # ----------- Process Slips
    vd_processes = []
    for item in os.listdir(args.folder):
        full_path = os.path.join(args.folder, item)
        if not os.path.isfile(full_path):
            continue
        if not item.endswith('.T04'):
            continue
        if item.startswith('_'):
            continue
        if item.startswith('.'):
            continue

        for ant in [0, 1]:
            cmd_list = [viewdat, '-i', '-c', f'--ant={ant}', full_path]
            txt_name = os.path.join(data_out_dir, item[0:-4] + f'_ant{ant}_cycle_slips.txt')
            if args.dry_run:
                continue

            txt_name_exist = os.path.isfile(txt_name) and os.path.getsize(txt_name) != 0
            #print(f'{txt_name} exits: {txt_name_exist}')
            if args.force or not txt_name_exist:
                print(' '.join(cmd_list) + ' > ' + txt_name)
                if not args.dry_run:
                    f = open(txt_name, 'w')
                    p = subprocess.Popen(cmd_list, stderr=subprocess.STDOUT, stdout=f)
                    vd_processes.append((p, f, txt_name))

    for p, f, log_name in vd_processes:
        if p is not None:
            p.wait()
        f.close()
        if p is not None:
            if p.returncode != 0:
                print(f'*** WARNING *** viewdat return code {p.returncode}')

    for item in os.listdir(data_out_dir):
        full_path = os.path.join(data_out_dir, item)
        if not os.path.isfile(full_path):
            continue
        if not item.endswith('_cycle_slips.txt'):
            continue

        csv_path = os.path.splitext(full_path)[0] + '.csv'
        if args.force or not os.path.isfile(csv_path):
            print(f'Processing {item}')
            df = viewdat_cycle_slips_txt_to_df(full_path)
            #print(df)
            df = df.reset_index()

            #feather_path = os.path.splitext(full_path)[0] + '.feather'
            #print(f'Saving {feather_path}')
            #df.to_feather(feather_path)

            print(f'Saving {csv_path}')
            df.to_csv(csv_path, index=False)
            print('Done')

            

    # ------------ Outputs
    df_list = []
    if args.plot:
        for item in os.listdir(data_out_dir):
            full_path = os.path.join(data_out_dir, item)
            if not os.path.isfile(full_path):
                continue
            if not item.endswith('_cycle_slips.csv'):
                continue

            print(f'Reading {full_path}')
            df = pd.read_csv(full_path)
            if df is None:
                print('   df is None')
                continue
            if df.empty:
                print('   df is empty')
                continue
            df_list.append(df)

            #vdl.FIGSIZE = (15, 5)
            #ylim = vdl.cno_ylim(df)
            #vdl.obs_plot_cno(df, html_base, ylim=ylim)

        df = pd.concat(df_list)

        for ant in df.ant.unique():
            #fig = plt.figure(figsize=(20, 8), constrained_layout=True)
            fig = plt.figure(figsize=(20, 6), constrained_layout=True)
            dfa = df.query(f'ant == {ant}')
            if dfa.empty:
                continue
            devs = sorted(dfa.dev.unique())
            N_devs = len(devs)
            #max_obs = float(dfa.num_obs.max()) *1.5
            #print(f'{max_obs=}')
            dfg = dfa.groupby(['SVType', 'Freq', 'dev'], sort=True, observed=True)[['num_slips', 'num_obs']].sum()
            max_slips = float(dfg.num_slips.max()) 
            print(f'{max_slips=}')
            max_slips = max_slips * 1.1
            print(f'{max_slips=}')
            for n_dev, dev in enumerate(devs):
                print(f'   Plotting: ant={ant}, {N_devs=}, {n_dev=}, {dev=}')
                dfq = dfa.query(f'dev=="{dev}"')
                if dfq.empty:
                    continue
                print(f'{dfq.num_slips.max()}')

                dft = dfq[['SVType', 'Freq', 'num_slips', 'num_obs']].copy()
                dfg = dft.groupby(['SVType', 'Freq'], sort=True, observed=True)[['num_slips', 'num_obs']].sum()
                #dfg['percent_slips'] = dfg.num_slips / dfg.num_obs 

                # Num Slips
                #ax = plt.subplot(3, N_devs, n_dev+1)
                ax = plt.subplot(1, N_devs, n_dev+1)
                dfg['num_slips'].plot(kind='barh', ax=ax)
                plt.title(f'{args.folder} ant{ant} {dev}')
                plt.xlabel('number of Cycle slips')
                ax.set_xlim([0, max_slips])

                # Num Obs
                #ax = plt.subplot(3, N_devs, N_devs+n_dev+1)
                #dfg['num_obs'].plot(kind='barh', ax=ax)
                #plt.xlabel('Number Observations')
                #plt.xlim([0, max_obs])

                # Percent Slips
                #ax = plt.subplot(3, N_devs, 2*N_devs+n_dev+1)
                #dfg['percent_slips'].plot(kind='barh', ax=ax)
                #plt.xlabel('percent of Cycle slips')
                #ax.set_xlim([0, 0.4])
                #ax.grid(True, axis='x')

            png_fname = os.path.join(fig_dir, f'ant-{ant}_num_slips.png')
            print(f'Saving {png_fname}')
            plt.savefig(png_fname)
            plt.close(fig)

        print('Done with plots')
    sys.exit()


    #pd.options.display.float_format = "{:,.3f}".format
    #print(df_m)

    #if args.html:
    #    print('Creating HTML Report')
    #    gen_html(args, df, df_m, meta)

    total_end_time = datetime.now()
    print('Elapsed time: ' + str(total_end_time-total_start_time))


if __name__ == '__main__':
    main()
