#!/usr/bin/python3
import json
import shlex
import subprocess

VERSION = 1

def proc_err(cmd, proc):
    # output process error and first line of error code
    return "{}{}".format(
        subprocess.CalledProcessError(proc.returncode, cmd, proc.stderr),
        " ({})".format(proc.stderr.splitlines()[0]) if proc.stderr.splitlines() else ""
    )

def print_data(data, error, error_msg):
    print(json.dumps({
        'data': data,
        'error': error,
        'errorString': error_msg,
        'version': VERSION
    }))

def main(args):
    CSV_HEADERS = {
        'tracking': [
            'reference_name',
            'reference_type',
            'stratum',
            'reference_time',
            'system_time',
            'last_offset',
            'rms_offset',
            'frequency',
            'residual_frequency',
            'skew',
            'root_delay',
            'root_dispersion',
            'update_interval',
            'leap_status',
        ],
        'sources': [
            'source_mode',
            'source_state',
            'source_name',
            'stratum',
            'polling_rate',
            'reachability',
            'last_rx',
            'adjusted_offset',
            'measured_offset',
            'estimated_error'
        ],
        'sourcestats': [
            'source_name',
            'number_samplepoints',
            'number_runs',
            'span',
            'frequency',
            'frequency_skew',
            'offset',
            'stddev',
        ]
    }
    DATA = {
        'tracking': {},
        'sources': []
    }
    ERROR = False
    ERROR_MSG = ''

    # get and set tracking data
    rc, tracking = subprocess.getstatusoutput('chronyc -c tracking')
    if rc != 0:
        print_data(DATA, rc, tracking)
        return 1
    tracking = tracking.split(',')
    for i in range(0, len(CSV_HEADERS['tracking'])):
        DATA['tracking'][CSV_HEADERS['tracking'][i]] = tracking[i]

    # get sources + sourcestats data
    rc, sources = subprocess.getstatusoutput('chronyc -c sources')
    if rc != 0:
        print_data(DATA, rc, sources)
        return 1
    sources = sources.split('\n')
    rc, sourcestats = subprocess.getstatusoutput('chronyc -c sourcestats')
    if rc != 0:
        print_data(DATA, rc, sourcestats)
        return 1
    sourcestats = sourcestats.split('\n')

    # mix sources and sourcestats
    for i in range(0, len(sources)):
        source = sources[i].split(',')
        stats = sourcestats[i].split(',')
        data = {}

        for j in range(0, len(CSV_HEADERS['sources'])):
            data[CSV_HEADERS['sources'][j]] = source[j]
        for j in range(0, len(CSV_HEADERS['sourcestats'])):
            data[CSV_HEADERS['sourcestats'][j]] = stats[j]

        DATA['sources'].append(data)

    print_data(DATA, ERROR, ERROR_MSG)

    return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv[1:]))
