import sys
import argparse
import json
import RXTools as rx
import datetime
import xmltodict
from colorama import Fore, Style
from collections import Counter

# Adjust if a proxy is required
proxies = {"http":  "",
           "https": ""}
#
# Simple script to get a summary report of the status of a receiver. Uses the same config JSON
# format as the DHS web app.
#

posLUT = {'PosFixedString':'RTK Fixed',
          'PosFloatString':'RTK Float',
          'PosSBASString':'SBAS',
          'PosRTKString':'RTK',
          'PosSBASStringPlus':'SBAS+',
          'PosHpString':'HP',
          'PosG2String':'G2',
          'PosVbsString':'VBS',
          'PosDGPSString':'DGNSS',
          'PosAutonString':'Autonomous',
          'PosOldString':'Old (No PVT)'}


if __name__ == "__main__":

  ######################################################################
  # Parse arguments
  parser = argparse.ArgumentParser(description='Receiver Summary')
  parser.add_argument('-s','--stations', help='Filename of the station JSON e.g. --stations global.json')
  parser.add_argument('-e','--errors', action="store_true", help='Show count of errors in errlog')
  parser.add_argument('-c','--checksum', action="store_true", help='Show the firmware checksum')
  args = parser.parse_args()
  ######################################################################
    
  showChecksum = False
  if(args.checksum):
    showChecksum = True

  # Load the list of stations
  if(args.stations):
    with open(args.stations,'r') as f: 
      data = json.load(f)

    stations = []
    gotStations = False
    # New JSON format
    for i in range(len(data)):
      if('RX' in data[i]):
        stations = data[i]['RX']
        gotStations = True
    
    # Old format
    if(gotStations == False):
      stations = data
  else:
    print('require a station JSON file')
    sys.exit(1)
 
  # Get color strings
  red      = Fore.RED
  yellow   = Fore.YELLOW
  endColor = Style.RESET_ALL
  bright   = Style.BRIGHT

  for thisStation in stations:
    nowStr = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    try:

      url = '/xml/dynamic/merge.xml?power=&errLog=&pos=&sysData='
      if(showChecksum):
        url += '&fw_status='

      resp = rx.SendHttpGet( thisStation.get("addr"), 
                             url,
                             thisStation.get("user"), 
                             thisStation.get("pw"),
                             verbose=False,
                             proxies=proxies,
                             timeout=5)
      data = xmltodict.parse(resp)
      uptime = data['data']['power']['uptime']
      thisUptime = float(uptime['day']) + float(uptime['hour'])/24.0 + float(uptime['min'])/1440.0 + float(uptime['sec'])/86400.0
      numLogEntries = int(data['data']['errLog']['numEntries'])
      posType = data['data']['pos']['position']['fixType']

      # Convert to a more human readable string
      if(posType[0] == '\\'):
        posType = posType[1:]
      elif(posType in posLUT.keys()):
        posType = posLUT[posType]

      numUsed = int(data['data']['pos']['position']['numFixSvs'])
      FWVer  = data['data']['sysData']['FWVersion']
      FWDate = data['data']['sysData']['FWDate']
      if(showChecksum):
        checksum = data['data']['fw_status']['active_checksum'].upper().zfill(8)
      
      errors   = 0
      warnings = 0
      if(numLogEntries > 0):
        unique_errs = Counter()
        unique_warns = Counter()
        errLog = data['data']['errLog']['entry']
        if(numLogEntries == 1):
          errLog = [errLog] # Force to a list
        for thisErr in errLog:
          flag = int(thisErr['flags']) & 7
          if(flag == 0):
            errors += 1
            unique_errs[thisErr['err']] += 1
          elif(flag == 3):
            warnings += 1
            unique_warns[thisErr['err']] += 1
       
      myStr = ('%15s %25s Up = %7.3f days Warn = %2d Err = %2d SvsUsed = %2d FW = %s(%s' %
               (thisStation.get("long"),
                thisStation.get("addr"),
                thisUptime,
                warnings,
                errors,
                numUsed,
                FWVer,
                FWDate))

      if(showChecksum):
        myStr += (' CS = %s' % checksum)

      myStr += (') Pos = %s' % posType)

      if(errors > 0):
        print('%s%s%s' % (red,myStr,endColor))
      elif(warnings > 0):
        print('%s%s%s' % (yellow,myStr,endColor))
      else:
        print(myStr)
      if args.errors and numLogEntries > 0:
        for k,v in unique_errs.items():
          print("%s %d:0x%s%s"%(red,v,k,endColor),end='')
        for k,v in unique_warns.items():
          print("%s %d:0x%s%s"%(yellow,v,k,endColor),end='')
        print('')

    except:
      print(bright+red+'Problem with:',thisStation.get("addr"),endColor)



