#!/usr/bin/env python3
#
# Format a result
#

import pscheduler
import sys
import math
from latency_utils import Histogram, format_float
from validate import result_is_valid



#Get format. Currently only support text/plain
try:
   format = sys.argv[1]
except IndexError:
   format = 'text/plain'

if format != 'text/plain':
    pscheduler.fail("Unsupported format '%s'" % format)
    
#parse JSON input
input = pscheduler.json_load(exit_on_error=True, max_schema=1)


#validate against JSON schema file
if "result" not in input:
    pscheduler.fail("Missing 'result' key in input passed to result-format")
valid, message = result_is_valid(input["result"])
if not valid:
    pscheduler.fail(message)

json = input["result"]
# get bucket width and default to 1ms
bucket_width = input.get('spec', {}).get('bucket-width', 0.001)

#Output basic stats
output = "\nPacket Statistics\n"
output += "-----------------\n"
output += "Packets Sent ......... %s packets\n" % json.get('packets-sent', 'Not Reported')
output += "Packets Received ..... %s packets\n" % json.get('packets-received', 'Not Reported')
output += "Packets Lost ......... %s packets\n" % json.get('packets-lost', 'Not Reported')
output += "Packets Duplicated ... %s packets\n" % json.get('packets-duplicated', 'Not Reported')
output += "Packets Reordered .... %s packets\n" % json.get('packets-reordered', 'Not Reported')

#Output one-way delay histogram
output += "\nOne-way Latency Statistics\n"
output += "--------------------------\n"
owd_hist = Histogram(json.get('histogram-latency', {}))
stats = owd_hist.get_stats(bucket_width=bucket_width, units=0.001)
output += format_float("Delay Median", stats.get('median', None), units="ms")
output += format_float("Delay Minimum", stats.get('minimum', None), units="ms")
output += format_float("Delay Maximum", stats.get('maximum', None), units="ms")
output += format_float("Delay Mean", stats.get('mean', None), units="ms")
output += "Delay Mode ........... " 
for mode in stats.get('mode', []):
    output += "%.2f ms " % mode 
output +=  "\n"
output += format_float("Delay 25th Percentile", stats.get('percentile-25', None), units="ms")
output += format_float("Delay 75th Percentile", stats.get('percentile-75', None), units="ms")
output += format_float("Delay 95th Percentile", stats.get('percentile-95', None), units="ms")
output += "Max Clock Error ...... %s ms\n" % json.get('max-clock-error', 'Not Reported')
output += "Common Jitter Measurements:\n"

if stats.get('percentile-95', None) and stats.get('median', None):
    output += "    P95 - P50 ........ %.2f ms\n" % (stats['percentile-95'] - stats['median'])
if stats.get('percentile-75', None) and stats.get('percentile-25', None):
    output += "    P75 - P25 ........ %.2f ms\n" % (stats['percentile-75'] - stats['percentile-25'])
output += format_float("    Variance", stats.get('variance', None), units="ms")
output += format_float("    Std Deviation", stats.get('standard-deviation', None), units="ms")
output += "Histogram:\n"
for owd_bucket in sorted(list(owd_hist.hist_dict.items()), key=lambda k: float(k[0])):
    output += "    %s ms: %d packets\n" % (owd_bucket[0], owd_bucket[1])
    
#Output TTL histogram
output += "\nTTL Statistics\n"
output += "--------------\n"
ttl_hist = Histogram(json.get('histogram-ttl', {}))
ttl_stats = ttl_hist.get_stats()
output += format_float("TTL Median", ttl_stats.get('median', None))
output += format_float("TTL Minimum", ttl_stats.get('minimum', None))
output += format_float("TTL Maximum", ttl_stats.get('maximum', None))
output += format_float("TTL Mean", ttl_stats.get('mean', None))
output += "TTL Mode ............. " 
for mode in ttl_stats.get('mode', []):
    output += "%.2f " % mode 
output +=  "\n"
output += format_float("TTL 25th Percentile", ttl_stats.get('percentile-25', None))
output += format_float("TTL 75th Percentile", ttl_stats.get('percentile-75', None))
output += format_float("TTL 95th Percentile", ttl_stats.get('percentile-95', None))
output += "Histogram:\n"
for ttl_bucket in sorted(list(json.get('histogram-ttl', {}).items()), key=lambda k: int(k[0])):
    output += "    %s: %d packets\n" % (ttl_bucket[0], ttl_bucket[1])

#output raw packets if we have them
if 'raw-packets' in json:
    output += "\nRaw packets\n"
    output += "----------\n"
    output +=  "SEQ SRC-TS SRC-CLOCK-SYNC SRC-CLOCK-ERR DST-TS DST-CLOCK-SYNC DST-CLOCK-ERR TTL\n"
    for p in json['raw-packets']:
        output += "%d %d %s %s %d %s %s %d\n" % (p['seq-num'], p['src-ts'], p['src-clock-sync'], p.get('src-clock-err', 'n/a'),  p['dst-ts'], p['dst-clock-sync'], p.get('dst-clock-err', 'n/a'), p['ip-ttl'])

#Print to stdout
print(output)
