#!/usr/bin/env python3
"""lrauv-log-critical.py

 Retrieve and process reliability information from LRAUV syslogs.  
    
    - walk server and locate all .dlist files
    - parse .dlist - get deployment/log names
    - scan syslog for '(CRITICAL)' messages
    - log critical messages and calc yr-by-yr and total runtimes.
    - eliminate redundant messages: use time bound on repeating errors

Last modified March, 2016
Ben Raanan, MBARI

"""
import argparse
import os

from scripts.syslog_tools import SysTools


# parse command-line arguments
parser = argparse.ArgumentParser(description='Process CRITICAL messages in LRAUV syslogs.')

parser.add_argument("-p", "--path", default='/mbari/LRAUV', type=str, help="set path to LRAUV data root")
parser.add_argument("-v", "--verbose", action="store_true", default=False, help="enable output verbosity")
parser.add_argument("-f", "--force", action="store_true", default=False, help="force fresh scan")
parser.add_argument("-r", "--report", action="store_true", default=False, help="generate csv reports w/out scan")
parser.add_argument("-s", "--sync", action="store_true", default=False, help="enable sync /var/www/html/ data folders")
parser.add_argument("-vh", "--vehicles", default=['tethys', 'daphne', 'makai', 'ahi', 'aku', 'opah', 'whoidhs', 'galene', 'brizo', 'pontus', 'triton'],
                    nargs='+', help="list of vehicles to process")
parser.add_argument("-i", "--ignore", default=['latest', 'lab', 'tank', 'battery', 'cal', 'none', 'logging'],
                    nargs='+', help="list of deployment name key-words to ignore")

args = parser.parse_args()


# define conversion functions
def td2hr(t): return t.total_seconds() / 3600  # Timedelta to hour
def fsize(f): return os.stat(f).st_size / 1e6  # file size in MB


def ignore_dlist(dlist_name):
    for i in args.ignore:
        if i in dlist_name.lower():
            print('Ignoring {} due to keyword match: {}.'.format(dlist_name, i))
            return True

    # don't ignore
    return False


stl = SysTools()
stl.set_sync(args.sync)

for vh in args.vehicles:

    if args.verbose:
        print('\nStarting syslog scan for LRAUV %s:' % vh, end='\n')

    # locate deployment/log files and load DataFrames
    stl.walkserver(args.path, vh)
    stl.load_dataframes(vh, args.force)

    modified = False  # only write files if data is modified
    folder_name = os.path.join(args.path, vh, "missionlogs")

    for yr in sorted(stl.deployments[vh].keys()):
        if stl.deployments[vh][yr]:

            for deployment in sorted(stl.deployments[vh][yr]):

                dlist_path = os.path.join(folder_name, yr, deployment)
                print("\n%s:" % dlist_path)
                stl.clear_dlist()
                stl.parse_dlist(dlist_path)
                if not ignore_dlist(stl.dlist['name']):

                    if args.verbose:
                        print("%s:" % stl.dlist['name'])

                    for log in sorted(stl.dlist['log']):

                        if not stl.already_processed(log):

                            syslog_path = os.path.join(dlist_path[:-6], log, "syslog")

                            if os.path.isfile(syslog_path) and fsize(syslog_path) > 0:
                                if args.verbose:
                                    print("     %s .... %.2fMB |" % (log, fsize(syslog_path)), end='')

                                stl.clear_runtime()
                                stl.scan_syslog(syslog_path)
                                modified = True

                                if args.verbose:
                                    cr_comp = ''
                                    if stl.critical['log'].str.contains(log).any():
                                        cr_comp = "comp: %s" % stl.critical.loc[stl.critical['log'] == log]['comp'].tolist()

                                    print(" runtime: %.2f hr | total: %.2f hr | %s" % (td2hr(stl.log_runtime),
                                                                                       td2hr(stl.total_runtime),
                                                                                       cr_comp))
                            else:
                                if args.verbose:
                                    print("     %s .... No syslog!" % log)
            if modified or args.report:
                stl.export_dataframes_csv(vh, yr)

    if modified:
        stl.export_dataframes_csv(vh)
        stl.export_dataframes_json(vh)

    if args.verbose:
        print('\nCompleted syslog scan for LRAUV %s.' % vh, end='\n\n')

stl.rm_localsys()
