#!/usr/bin/env python

#######################################################
# Copyright Trimble Inc 2021
# Purpose: For plotting out various plots to assist with 
#          radio testing to do with increasing correction 
#          age. See TT-14373 
# Contributor(s): Joshua_McLean@Trimble.com, 
#######################################################

import argparse
import os
import sys
import re

import matplotlib
import mutils as m
import numpy as np

#from mutils import *

parser = argparse.ArgumentParser(description='Generate .png plots for record 99 CorrLibBytes diagnostic')
parser.add_argument('filename', help='T0x filename')
parser.add_argument('--fig', help='Output plots in Matlab fig instead of PNG', action='store_true')
parser.add_argument('--opt', help='Extra args to pass on to Viewdat.exe. example --opt=\"-s34000 and -e35000\"', default=None, type=str)
args = parser.parse_args()

# Allow running headless from the command line
if (args.fig == False):
    matplotlib.use("agg")

if (args.opt != None):
    d=m.cmd2arr_raw("VIEWDAT.exe -d35:2,99 -mb " + args.opt + " \"" + args.filename + "\"")
else:
    d=m.cmd2arr_raw("VIEWDAT.exe -d35:2,99 -mb \"" + args.filename + "\"")


gpsSeconds = []

tc0x98_sub29 = []
tc0x98_sub10 = []
tc0x98_sub16 = []
tc0x98_sub11 = []
tc0x93 = []
totalBytes = []
totalBytesCalc = []

val_0x98_sub29 = 0
val_0x98_sub29_padding = 0
val_0x98_sub10 = 0
val_0x98_sub16 = 0
val_0x98_sub11 = 0
val_0x93 = 0
val_total = 0

isCMR = False
isRTCM = False

tc0x98_rtcmSub1007_2 = []
tc0x98_rtcmSub1073 = [] #GPS
tc0x98_rtcmSub1083 = [] #GLONASS
tc0x98_rtcmSub1093 = [] #GALILEO
tc0x98_rtcmSub1113 = [] #QZSS
tc0x98_rtcmSub1123 = [] #BEIDOU

val_0x98_rtcmSub1007_2 = 0
val_0x98_rtcmSub1073 = 0
val_0x98_rtcmSub1083 = 0
val_0x98_rtcmSub1093 = 0
val_0x98_rtcmSub1113 = 0
val_0x98_rtcmSub1123 = 0
val_total_rtcm = 0

i = 0 # skip first

gpsWeek = -1
gpsSecond = -1
process = False
next = False
gpsSecondFirst = -1

while i < len(d): 

    line = d[i]
    i += 1

    #likely to be record 35:2
    if (len(line) > 300):
        data = line.split('\t')
        if (len(data) > 90):

            temp = float(data[1])
            if (temp % 1.0 == 0):
                try:
                    
                    if gpsSecond != -1:

                        if (isRTCM):

                            tc0x98_rtcmSub1073.append(val_0x98_rtcmSub1073)
                            tc0x98_rtcmSub1083.append(val_0x98_rtcmSub1083)
                            tc0x98_rtcmSub1093.append(val_0x98_rtcmSub1093)
                            tc0x98_rtcmSub1113.append(val_0x98_rtcmSub1113)
                            tc0x98_rtcmSub1123.append(val_0x98_rtcmSub1123)                            
                            tc0x98_rtcmSub1007_2.append(val_0x98_rtcmSub1007_2)
                            totalBytes.append(val_total_rtcm)


                            calc = val_0x98_rtcmSub1073 + 6
                            calc += val_0x98_rtcmSub1083 + 6
                            calc += val_0x98_rtcmSub1093 + 6
                            calc += val_0x98_rtcmSub1113 + 6
                            calc += val_0x98_rtcmSub1123 + 6

                            if (val_0x98_rtcmSub1007_2 > 0):
                                calc += val_0x98_rtcmSub1007_2 + 6

                            if (calc != val_total_rtcm):
                                print ('%.1fs: calc %d vs total %d mismatch' % (gpsSecond, calc, val_total_rtcm))

                            totalBytesCalc.append(calc)                   
                            gpsSeconds.append(gpsSecond)

                        if (isCMR):
                            #append collected data
                            tc0x98_sub29.append(val_0x98_sub29)
                            tc0x98_sub10.append(val_0x98_sub10)
                            tc0x98_sub16.append(val_0x98_sub16)
                            tc0x98_sub11.append(val_0x98_sub11)
                            tc0x93.append(val_0x93)
                            totalBytes.append(val_total)

                            calc = val_0x98_sub29 + val_0x98_sub29_padding
                            calc += val_0x98_sub10 + 6
                            calc += val_0x98_sub16 + 6
                            calc += val_0x98_sub11 + 6
                            calc += val_0x93 + 6

                            if (calc != val_total):
                                print ('%.1fs: calc %d vs total %d mismatch' % (gpsSecond, calc, val_total))

                            totalBytesCalc.append(calc)                       
                            gpsSeconds.append(gpsSecond)

                    gpsWeek = int(data[0])
                    gpsSecond = int(round(temp))

                    if ((gpsSecond > 0) and (gpsSecondFirst == -1)):
                        gpsSecondFirst = gpsSecond

                    #handle gps second rollover
                    if (gpsSecond < gpsSecondFirst ):
                        gpsSecond += 604800; #60 * 60 * 24 * 7                    

                    val_0x98_sub29 = 0
                    val_0x98_sub29_padding = 0
                    val_0x98_sub10 = 0
                    val_0x98_sub16 = 0
                    val_0x98_sub11 = 0
                    val_0x93 = 0
                    val_total = 0
                   
                    val_0x98_rtcmSub1073 = 0
                    val_0x98_rtcmSub1083 = 0
                    val_0x98_rtcmSub1093 = 0
                    val_0x98_rtcmSub1113 = 0
                    val_0x98_rtcmSub1123 = 0
                    val_0x98_rtcmSub1007_2 = 0
                    val_total_rtcm = 0
                    
                    process = True
                except:
                    continue

    if gpsWeek == -1:
        continue

    if process == False:
        continue
    
    if (isCMR == False):

        if line.startswith(' encodeRTCM3Type1007_2:'):
            isRTCM = True
            data = re.split(' |:', line)

            val_0x98_rtcmSub1007_2 = int(data[5])
            val_total_rtcm = int(data[10])

            if (val_0x98_rtcmSub1007_2 <= 0 or val_total_rtcm <= 0):
                print('Invalid line: %s' % (line))

        if line.startswith(' encodeRTCM3TypeMSM:'):
            isRTCM = True
            data = re.split(' |:', line)

            if (len(data) >= 13):

                size = int(data[5])
                type = ''
                val_total_rtcm = 0
                
                if ('1073(GPS)' in line):
                    type = data[12]
                    val_total_rtcm = int(data[9])
                else:
                    type = data[11]
                    val_total_rtcm = int(data[8])

                if (type == '1073(GPS)'):
                    val_0x98_rtcmSub1073 = size
                
                elif (type == '1083(GLONASS)'):
                    val_0x98_rtcmSub1083 = size   

                elif (type == '1093(GALILEO)'):
                    val_0x98_rtcmSub1093 = size 

                elif (type == '1113(QZSS)'):
                    val_0x98_rtcmSub1113 = size 

                else:
                    print('Unknown type %s in line: %s' % (type, line))

            else:
                print('%s len %s' % line, len(data))


        if (line.startswith (' encodeRTCM3SplitMSM:')):
            isRTCM = True

            data = re.split(' |:', line)

            size = int(data[5])
            val_total_rtcm = int(data[8])

            type = data[11]

            if (type == '1123(BDS)'):
                val_0x98_rtcmSub1123 = size 
            else:
                print('Unknown type %s in line: %s' % (type, line))

    if (isRTCM == False):
    
        if line.startswith('TC '):
            isCMR = True
            data = re.split(' |,|:', line)

            #there can be more than 2 sub-29 within 1 package
            if line.startswith('TC 0x98-sub: 29'):
                val_0x98_sub29 += int(data[9])
                val_0x98_sub29_padding += 6

            if line.startswith('TC 0x98-sub: 10'):
                val_0x98_sub10 = int(data[9])

            if line.startswith('TC 0x98-sub: 16'):
                val_0x98_sub16 = int(data[9])

            if line.startswith('TC 0x98-sub: 11'):
                val_0x98_sub11 = int(data[9])

            if line.startswith('TC 0x93'):
                val_0x93 = int(data[6])
                next = True

        if next and line.startswith('CorrLibBytes'): 
            isCMR = True       
            data = re.split(' |,|:', line)
            val_total = int(data[2])        
            #print('%.1f,%s' % (gpsSecond, data[2]))
            next = False
        


if len(gpsSeconds) == 0:
    print ('No valid data found!')
    exit()


fig = m.figure()

if (isCMR):

    m.plot( gpsSeconds, tc0x98_sub29, ".", label='0x98 Sub 29', markersize=2)
    m.plot( gpsSeconds, tc0x98_sub10, ".", label='0x98 Sub 10', markersize=2)
    m.plot( gpsSeconds, tc0x98_sub16, ".", label='0x98 Sub 16', markersize=2)
    m.plot( gpsSeconds, tc0x98_sub11, ".", label='0x98 Sub 11', markersize=2)
    m.plot( gpsSeconds, tc0x93, ".", label='0x93', markersize=2)
    m.plot( gpsSeconds, totalBytes, ".", label='Total bytes', markersize=2)

    m.title("Rec 99 CorrLib Bytes sent\n[" + os.path.basename(args.filename) + "]")
    m.xlabel('GPS Second')
    m.ylabel('Bytes sent')

if (isRTCM):
    m.plot( gpsSeconds, tc0x98_rtcmSub1073, ".", label='Sub 1073', markersize=2)
    m.plot( gpsSeconds, tc0x98_rtcmSub1083, ".", label='Sub 1083', markersize=2)
    m.plot( gpsSeconds, tc0x98_rtcmSub1093, ".", label='Sub 1093', markersize=2)
    m.plot( gpsSeconds, tc0x98_rtcmSub1113, ".", label='Sub 1113', markersize=2)
    m.plot( gpsSeconds, tc0x98_rtcmSub1123, ".", label='Sub 1123', markersize=2)
    m.plot( gpsSeconds, tc0x98_rtcmSub1007_2, ".", label='Sub 10072_2', markersize=2)
    m.plot( gpsSeconds, totalBytes, ".", label='Total bytes', markersize=2)

    m.title("Rec 99 CorrLib Bytes sent\n[" + os.path.basename(args.filename) + "]")
    m.xlabel('GPS Second')
    m.ylabel('Bytes sent')

m.grid(True)
m.legend(loc='best')
m.tight_layout()

fig.gca().set_ylim(-12, 700) #20s

if (args.fig == True):
    m.show()
else:
    pngName = args.filename + '_rec99_plot_corrlibbytes.png'
    m.savefig(pngName)
    print('saved %s' % pngName)