#!/usr/bin/python3
import json
import re
import subprocess
from subprocess import Popen, PIPE
from jdsu.mts.ScpiAccess import ScpiAccess, EsrError
import time
import datetime
import os
from os import path
import sys
import syslog
from collections import defaultdict
from collections import OrderedDict
from decimal import Decimal

#############################################################
def userlog_ufom_monitoring(mond_time, monitoring_info, lrc):
    ufom_script = os.path.abspath(__file__)
    syslog.syslog(syslog.LOG_WARNING, ufom_script)
    syslog.syslog(syslog.LOG_WARNING, monitoring_info )
    return True

#############################################################################
def set_ufom_monitoring_state(cmnd):
    mrc = 0
    ufom_status = []

    op_test = ['empty','running']
    testing_in_prog = "a_test_is_already_running"
    test_empty = "test_is_empty"
    
    try:
        #
        #  Set UFOM Monitoring State
        #  "OTU:UFOM:INIT:cmnd"
        monreq_status = otu_p.SendCommand("OTU:UFOM:%s"%cmnd)
        ufom_status = \
             OrderedDict([("status" , "success") ])  
    except Exception as error_e:
        mrc += 1
        ufom_status = \
             OrderedDict([("status" , "failure") ])

        try:
            status_rsp = str(otu_p.SendAndReadCommand("OTU:UFOM:INIT:STATUS?")).lower()
            if status_rsp not in op_test:
                ufom_status["message"] = status_rsp
            elif status_rsp == op_test[1]:
                ufom_status["message"] = testing_in_prog
            else:
                ufom_status["message"] = test_empty       
        except Exception as error_e1:
            ufom_status["message"] = ACCESS_ERROR

    return (ufom_status, mrc)
    
###############################################################################
def send_stat_msg_to_console(resp_msg):
    sys.stdout.write(json.dumps(resp_msg, sort_keys=False, indent=4))
    sys.stdout.write("\n")
    sys.stdout.flush()
    return True
    
#############################################################################
def get_ufom_monitoring_status():
    mrc = 0
    ufom_status = []
    op_state = ['empty', 'auto_parameter_in_progress']
    rs_state = ['running', 'stopped']
    no_test_running= "stopped"
    test_wip = "configuring_auto_test"

    try:
        #
        #  Get UFOM Monitoring Status
        #  "OTU:UFOM:INIT:STATUS?"
        monitoring_status = otu_p.SendAndReadCommand("OTU:UFOM:INIT:STATUS?")
        status_rsp = str(monitoring_status).lower()
        if status_rsp in rs_state:
            ufom_status = \
                OrderedDict([("status" , status_rsp)])
        elif status_rsp in op_state[1]:
            ufom_status = \
                OrderedDict([("status" , test_wip), \
                             ("message", status_rsp)])
        else:
            ufom_status = \
                OrderedDict([("status" , no_test_running), \
                             ("message", monitoring_status)])
    except Exception as error_e:
        mrc += 1
        ufom_status = \
             OrderedDict([("status" , "failure"), \
                          ("message", ACCESS_ERROR)])
    return (ufom_status, mrc)
 
#############################################################################
def check_ufom_licence():
    mrc = 0
    ufom_status = []
    lc_state_available = 'AVAILABLE'
    lc_state_invalid ='invalid license'
    
    try:
        #
        #  Open SCPI connections
        otu_p = ScpiAccess("localhost", 1400, 30, "*PASS \"RTU\"\"PASSWORD\"\n")
        #  Get UFOM Monitoring Status
        #  "OTU:SYST:OPTION:STATUS? ULTRAFAST_MON"
        license_status = otu_p.SendAndReadCommand("OTU:SYST:OPTION:STATUS? ULTRAFAST_MON")
        status_rsp = str(license_status).lower()
        if status_rsp != lc_state_available.lower():
            mrc = 1
            ufom_status = \
                OrderedDict([("status" , "failure"), \
                             ("message", lc_state_invalid)])
        else:
            mrc = 0
            otu_p.disconnect()
    except Exception as error_e:
        mrc = 1
        ufom_status = \
             OrderedDict([("status" , "failure"), \
                          ("message", ACCESS_ERROR)])
    return (ufom_status, mrc)

##############################################################################
#<><><><><><><>-------<><><><><><><>-------<><><><><><><>-------<><><><><><><>

if __name__ == "__main__":
    MAX_SCRIPTINPUTS = 2
    MAX_NUM_OF_INPUT_ARGUMENTS = MAX_SCRIPTINPUTS - 1
    FAILED_STATUS = "failure"
    SUCCESS_STATUS = "success"
    MON_STAT = "status"
    ACCESS_ERROR = "Command Access Error"
    
    requested_mon_type = "none"
    monitoring_reqtypes = ['status', 'start', 'stop']
    fl_count = ['file_count']
    ufom_monitoring_lic_state = ()
 
    err_details = ""
    grc = 0

    start_time_date = time.strftime("%c")
    start_time = time.time()
    syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_USER)
    #
    #  Check if UFOM Licence is available
    ufom_monitoring_lic_state, grc = check_ufom_licence()
    if ( grc > 0 ):
        userlog_ufom_monitoring(start_time_date, json.dumps(ufom_monitoring_lic_state, sort_keys=False, indent=4), grc)
        send_stat_msg_to_console(ufom_monitoring_lic_state)
        exit(grc)
    #
    #  Validate the the number of input arguments
    mroot_arguments = len(sys.argv)
    if mroot_arguments != MAX_SCRIPTINPUTS:
        grc = 1
        err_details = "Number of input arguments must be "+str(MAX_NUM_OF_INPUT_ARGUMENTS)
        ufom_status = \
             OrderedDict([("status" , "failure"), \
                           ("message", err_details)])
        userlog_ufom_monitoring(start_time_date, json.dumps(ufom_status, sort_keys=False, indent=4), grc)
        send_stat_msg_to_console(ufom_status)
        exit(grc)
    #
    #
    mon_type = sys.argv[1]
    monitoring_type = mon_type.lower()
    if monitoring_type in monitoring_reqtypes:
        #
        #  Open SCPI connections
        otu_p = ScpiAccess("localhost", 1400, 30, "*PASS \"RTU\"\"PASSWORD\"\n")
        grc = 0
        ufom_monitoring = OrderedDict()    
        #
        #
        if (monitoring_type in MON_STAT):
            #
            #  Get monitoring status
            ufom_monitoring, grc = get_ufom_monitoring_status()
        else:
            #
            #  Set monitoring state
            ufom_monitoring, grc = set_ufom_monitoring_state(str(monitoring_type))
        #
        #
        userlog_ufom_monitoring(start_time_date, \
                                       ("  req parameter = "+str(sys.argv[1])+";\n" \
                                       +"  cli response = "+json.dumps(ufom_monitoring)+"\n"), grc)        
        send_stat_msg_to_console(ufom_monitoring)
    elif mon_type in fl_count:
        #
        cmd = os.popen('ls -alt /otu/UFOM/*.csv 2> /dev/null | wc -l')
        csv_count = cmd.read()
        cmd.close()
        #
        #
        cmd = os.popen('ls -alt /otu/UFOM/*.sor 2> /dev/null | wc -l')
        sor_count = cmd.read()
        cmd.close()
        ufom_fl_count = \
                    OrderedDict([("csv_count", int(csv_count)), \
                                 ("sor_count", int(sor_count))])
        userlog_ufom_monitoring(start_time_date, \
                                       ("  req parameter = "+str(sys.argv[1])+";\n " \
                                       +"  cli response = "+json.dumps(ufom_fl_count)+"\n"), grc)
        send_stat_msg_to_console(ufom_fl_count)
    else:
        grc = 1
        err_details = "Input parameter must be either status, start, stop or file_count"
        ufom_status = \
             OrderedDict([("status" , "failure"), \
                           ("message", err_details)])
        userlog_ufom_monitoring(start_time_date, json.dumps(ufom_status, sort_keys=False, indent=4), grc)
        send_stat_msg_to_console(ufom_status)    
    exit (grc)
