#!/usr/bin/env python

#######################################################
# Copyright Trimble Inc 2021
# Purpose: For plotting out data from Record 33 type 4 (RTX / MSS / Omnistar Signal Info)
# Contributor(s): Joshua_McLean@Trimble.com, 
#######################################################

import argparse
import os
from pickle import TRUE
import sys
from tabnanny import check

import matplotlib
import mutils as m
import numpy as np

from matplotlib.ticker import (MultipleLocator, FormatStrFormatter,
                               AutoMinorLocator)

parser = argparse.ArgumentParser(description='Generate .png plots for record 98 (delta times per type) and record 35:2 (age and satellite tracking)')
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('--label', help='Plot sub label override. If none is specified, the file name is used', required=False, default=None, type=str)
parser.add_argument('--max_y', help='Max y for plot. 60 is the default', required=False, default=60, type=int)
parser.add_argument('--min_y', help='Min y for plot. 0 is the default', required=False, default=0, type=int)
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")

maxY = args.max_y
minY = args.min_y


if (args.opt != None):
    d=m.cmd2arr("VIEWDAT.exe -d33:4 -mb " + args.opt + " \"" + args.filename + "\"")
else:
    d=m.cmd2arr("VIEWDAT.exe -d33:4 -mb \"" + args.filename + "\"")

plotSubLabel = args.label

if (plotSubLabel == None):
    plotSubLabel = os.path.basename(args.filename)

def plot_record33_4( d, filename, label, index, maxY = None, minY = None ):
  
    if len(d) == 0:
        return

    snrs = d[:,index]
    time = d[:,1]

    count  = len(time)
    start = time[0]
    end = time[len(time) - 1]

    print(start)
    print(end)

    seconds = []
    values = []
    valuesWithZeroOrNaN = []
    valuesPow10 = []
    rolloverOccured = False
    rolloverCount = 0

    #if end < start:
    #    end += (60 * 60 * 24 * 7) #604800
    #    rolloverOccured = True
    #    rolloverCount += 1

    zeroCounter = 0
    zeroCounterStartGpsTime = 0
    offset = 0




    waitingForRollover = False

    rollingAvgSnr = []
    rollingAvgTime = []

    for i in range(count):

      #print ("i = %d" % i)

      snr = snrs[i]
      gpsTime = time[i]

   
      if ((waitingForRollover == False) and (gpsTime > 100_000)):
        waitingForRollover = True
      elif ((waitingForRollover == True) and (gpsTime < 100_000)):
        waitingForRollover = False
        rolloverCount += 1
        print ("Rollover count: %d" % rolloverCount)

      gpsTime += (rolloverCount * 604800) # (60 * 60 * 24 * 7)

      rollingAvgSnr.append(snr)
      rollingAvgTime.append(gpsTime)

      if (len(rollingAvgSnr) >= 10):
        avgSnr = np.average(rollingAvgSnr)
        avgTime = np.average(rollingAvgTime)
        rollingAvgSnr = []
        rollingAvgTime = []
        seconds.append(avgTime)
        values.append(avgSnr)   

      valuesPow10.append(pow(10, snr / 10.0 ))


    print ("Total rollover count: %d" % rolloverCount)
    

#    for sec in np.arange(start, end, 1.0):  
#        
#        #Note - rec 33-4 doesn't have record every second.
#        mssGpsTime = time[offset]
#
#        #check for rollover
#        if mssGpsTime < start:        
#          if (rolloverOccured):
#              mssGpsTime += (60 * 60 * 24 * 7) #604800
#          else:
#              offset += 1
#              print("Invalid gps time detected = %d. Skipping" % mssGpsTime) #can occur with DA2..
#
#        seconds.append(sec)
#
#        #sec need to catch up
#        if (mssGpsTime > sec):
#          if (zeroCounter > 5):
#            valuesWithZeroOrNaN.append(0) #add 0 to have them visible in the plot
#          else:
#            valuesWithZeroOrNaN.append(np.nan) #nan to reduce 0 noise as small gaps ( < 5s) are expected
#
#          if (zeroCounter == 0):
#            zeroCounterStartGpsTime = sec
#          
#          zeroCounter += 1
#        else:
#          valuesWithZeroOrNaN.append(values[offset])      
#          valuesPow10.append(pow(10, values[offset] / 10.0 ))       
#          offset += 1
#
#          if (zeroCounter > 5):
#
#            minutes = 0
#            if (zeroCounter > 60):
#              minutes = zeroCounter / 60.0
#
#            if (minutes > 0):
#              print('[%ds - %ds] Gap duration: %d seconds (%.1f minutes)' % (zeroCounterStartGpsTime, sec, zeroCounter, minutes)) #debug msg
#            else:
#              print('[%ds - %ds] Gap duration: %d seconds' % (zeroCounterStartGpsTime, sec, zeroCounter)) #debug msg
#                  
#          zeroCounter = 0 #reset counter
#          zeroCounterStartGpsTime = 0
#
#        if (offset >= len(time)):
#          print('Warning: offset %d greater than len(time) %d?? Breaking out early..' % (offset, len(time)));  
#          break

    weightedAvgSNRs = np.log10(np.average(valuesPow10)) * 10.0

    fig = m.figure()
    ax = fig.add_subplot(1, 1, 1)
    m.plot( seconds, values, ".", markersize=2, label="%s [%.1f]" % ("MSS SNR Wgt Avg", weightedAvgSNRs))

    m.title("Rec 33:4 " + label + " (MSS SV)\n[" + plotSubLabel + "]")
    m.xlabel('GPS Second')
    m.ylabel(label)
    m.legend(loc='upper right')

    m.grid(True)
    m.tight_layout()

    ax.yaxis.grid(True, which='minor', linestyle=':', color='lightgrey')
    ax.yaxis.set_major_locator(MultipleLocator(10))
    ax.yaxis.set_major_formatter(FormatStrFormatter("%d"))
    ax.yaxis.set_minor_locator(MultipleLocator(2))

    if (args.fig == True):
        m.show()
    else:
      fig.gca().set_ylim(maxY, minY)

      pngName = filename + '_rec33-4_' + label + '.png'
      m.savefig(pngName)  

      print('saved %s' % pngName)

    return

plot_record33_4(d, args.filename, 'CNo', 4, minY - 2, maxY)
#plot_record33_4(d, args.filename, 'IQ', 5)
