#!/usr/bin/python3

# Script only suited to the mts family

import sys
import json
from subprocess import check_output, Popen
from time import sleep
from viavi.mts.ScpiAccess import ScpiAccess

sys.stdout = open('/tmp/mts-fiber-launch.log', 'w')

# Count the arguments
arguments = len(sys.argv) - 1
print ('The script %s is called with %i arguments' % (sys.argv[0], arguments))

# Output arguments
position = 1
cdmFunction = None
jsonStr = None
testPlanIdx = None
testLocIdx = None
while (arguments >= position):
    print ('Parameter %i: %s' % (position, sys.argv[position]))
    if position == 1:
        cdmFunction = sys.argv[position]
    if position == 2:
        jsonStr = sys.argv[position]
    if position == 3:
        testPlanIdx = sys.argv[position]
    if position == 4:
        testLocIdx = sys.argv[position]
    position += 1

# Test against CDM test.type values that we manage with this script (not the ISU/FO function names)
# (CDM test type is not the same thing as ISU functions list content)
if cdmFunction is None or cdmFunction not in ['OTDR','fcompPro','trueFiber','optiTrak','bidirIlOrl']:
    print ('The cdm test type %s requested is not supported!' % (cdmFunction))
    sys.stdout.close()
    sys.exit(1)

if jsonStr is None:
    print ('Empty or no json provided!')
    sys.stdout.close()
    sys.exit(1)

if testPlanIdx is None:
    print ('No test plan index provided!')
    sys.stdout.close()
    sys.exit(1)

if testLocIdx is None:
    print ('No test locations index provided - assuming 0')
    testLocIdx = 0

jsonContent = json.loads(jsonStr)
print ('Parameter JSON:\n%s\n' % (json.dumps(jsonContent, indent=4, sort_keys=False)))

#ISU port number
port = 8000

if port is None:
    print ('Cannot find Fiber ISU port!')
    sys.stdout.close()
    sys.exit(1)

# Check if the FiberOptic is running
foRunning = True
try:
    pidFO = check_output(['pidof', 'Fiber_Optic'])
    print ('FO running with PID: %s' % (pidFO))
except:
    foRunning = False
    print ('FO not running...')

# Connecting to Fiber-ISU port and sending SCPI commands
isu = ScpiAccess('127.0.0.1', port)

isuFunction = None
isuFunction2 = None
# Determine which ISU function is needed for a particular CDM test type
# (For the OTDR, this requires looking at the otdrTopology value held in configuration)
testType = jsonContent.get('type', '')
config = jsonContent.get('configuration', '')
if testType == 'OTDR':
    print( 'Launching an OTDR test')
    isuFunction = 'OTDR'  # default value if we have a badly formed OTDR test (with no otdrTopology)
    if config:
        otdrSettings = config.get('otdrSettings')
        if otdrSettings:
            topology = otdrSettings.get('otdrTopology')
            if topology:
                # We can use a specific type of OTDR test
                print( 'OTDR type = %s' % (topology))
                otdrDict = { 'Expert-SM':'OTDR',
                     'Expert-P2P':'OTDR',
                     'Expert-PON':'OTDR',
                     'Expert-MM':'OTDR-MM',
                     'SmartTest-SM':'OTDR-Y',
                     'SmartTest-MM':'OTDR-MM-Y',
                     'FTTA-SM':'FTTA_SM',
                     'FTTA-MM':'FTTA_MM',
                     'FTTH': 'FTTH_SLM',
                     'Loopback':'TESTPRO',
                     'Enterprise-SM':'ENTERPRISE_SM',
                     'Enterprise-MM':'ENTERPRISE_MM',
                     'bidirOtdr':'TESTPRO'
                     }
                isuFunction = otdrDict.get(topology, 'OTDR')
                print( '-> requires %s' % (isuFunction) )
                if isuFunction == 'TESTPRO':
                    isuFunction2 = 'FIX'

if testType == 'fcompPro':
    if config:
        measSeq = config.get('measurementSequence')
        print('FCompPRO type = %s' % (measSeq))
    isuFunction = 'TESTPRO'
    isuFunction2 = 'FIX'

if testType == 'bidirIlOrl':
    if config:
        measSeq = config.get('measurementSequence')
        print('bidirIlOrl type = %s' % (measSeq))
    isuFunction = 'TESTPRO'
    isuFunction2 = 'FIX'

if testType == 'optiTrak':
    print('optiTrak test type')
    isuFunction = 'TRUE-FIBER'

if testType == 'trueFiber':
    print('trueFiber test type (ATT)')
    isuFunction = 'TRUE-FIBER'

# Need to check homepage content to establish if the required function is available AND already turned **ON**
# if it is
#   we could just raise the Fiber Gui
# but in all cases
#   launch otdr script with to make sure the desired function is ON
print("Looking for %s (or %s) required function in Fiber Optics solution" % (isuFunction, isuFunction2))
found = False
#params = str(port) + ' '
for pos in ['PWRS', 'OPPS', 'BOTH']:
    found = False
    for slic in ['SLIC1', 'SLIC2', 'SLIC3', 'SLIC4', 'SLIC5', 'SLIC6', 'SLIC7', 'BASE']:
        tmpArg = pos + ',' + slic
        tmpCmd = 'MOD:FUNC:LIST? ' + tmpArg
        tmpReply = isu.SendAndReadCommand(tmpCmd)
        print ('Checking : %s --> %s' % (tmpCmd, tmpReply))
        if isuFunction in str(tmpReply):
            print ('Found %s function available at %s' % (isuFunction, tmpArg))
            #params += tmpArg
            otdrPos = tmpArg
            found = True
            # This means we are always using the *First* one found (even if a second possibility is already ON)
            break
        elif isuFunction2 != None:
            print ('Double Checking : %s --> %s' % (tmpCmd, tmpReply))
            if isuFunction2 in str(tmpReply):
                print ('Found %s function available at %s' % (isuFunction2, tmpArg))
                #params += tmpArg
                otdrPos = tmpArg
                found = True
                isuFunction = isuFunction2
                break
    if found:
        break

if not found:
    print ('Cannot determine position and level(slice) for the %s function!' % (isuFunction))
    isu.disconnect()
    sys.stdout.close()
    sys.exit(1)

#params += ' '
#params += isuFunction
#params += ' ON'

# Now select the function (turn it on)
fncmd = 'MOD:FUNC:SEL ' + otdrPos + ',"%s"' % (isuFunction) + ', ON'
print ('Selecting function, cmd: \n%s' % (fncmd))
isu.SendCommand(fncmd)
# and update the current function
currentcmd = 'MOD:FUNC:CURR ' + otdrPos + ',"%s"' % (isuFunction)
print ('Current function, cmd: \n%s\n' % (currentcmd))
isu.SendCommand(currentcmd)
# + Need to force focus away from IJM


# Waiting until the Fiber_Optic is started and initialized
ret = isu.SendAndReadCommand('PROC:STAT? "Fiber_Optic"')
while ret.find('ACTIVATED') < 0:
    print ('FiberOptic not activated yet - %s' % (ret))
    sleep(0.25)
    ret = isu.SendAndReadCommand('PROC:STAT? "Fiber_Optic"')

# Above is good first step but not enough to be certain the OTDR is turned on (ISW-1349)
# Wait until select query returns ON
tmpCmd = 'MOD:FUNC:SEL? ' + otdrPos + ',"%s"' % (isuFunction)
print('Querying state: %s' % (tmpCmd))
ret = isu.SendAndReadCommand(tmpCmd)
while ret.find('ON') < 0:
    print ('OTDR feature not selected yet - %s' % (ret))
    sleep(0.25)
    print ('Querying state: %s' % (tmpCmd))
    ret = isu.SendAndReadCommand(tmpCmd)

# Execute the SCPI command that passes all needed parameters to Fiber_Optic
cmd = 'WORK:TPIL ' + str(testPlanIdx) + "," + str(testLocIdx) + ",'" + str(jsonStr) + "'"
print ('Sending cmd: \n%s\n' % (cmd))
isu.SendCommand(cmd)

print ('\nDONE\n')
isu.disconnect()
sys.stdout.close()
sys.exit(0)
