#!/usr/bin/env python

'''
usage:  1. observe name:type ...  # reads name:type list from command line
        2. observe                # reads name:type list from stdin
'''


import sys
import time
import coredata


builders = { 'bool': coredata.bool, 
             'int32': coredata.int32, 
             'double': coredata.double, 
             'string': coredata.string, 
             'string_int_map' : coredata.string_int_map,
             'timestamped_int32': coredata.timestamped_int32 }

startTime = time.time ()


def parse (string):
    'Parses a string into a list of tuples of strings: [(name, type), ...]'
    result = []
    for identifier in string.split ():
        (name, type) = identifier.split (':')
        result.append ((name, type))
    return result


def datums (pairs):
    'Transforms a list of tuples describing datums into datums.'
    result = []
    for (name, type) in pairs:
        builder = builders[type]
        result.append (builder (name))
    return result


def printer (datum, value):
    now = time.time () - startTime
    seconds = int (now)
    milliseconds = int (now % 1 * 1000)
    print '[%3ds %03dms] %s: %s' % (seconds, milliseconds, datum.name, value)


def watch_pairs (pairs, callback=printer):
    'Register a callback for each of the datums in the given pairs list.'
    watch_datums (datums (pairs), callback)


def watch_datums (datums, callback=printer):
    'Register a callback for each of the datums in the given list.'
    for datum in datums:
        datum.onChanged (printer)


if __name__ == '__main__':
    print 'observe:  CoreData datum analysis tool by Ryan Kuester'
    print 'usage:  1. observe datum_name:type ... <- datum watch list from CLI '
    print '        2. observe <- datum_name:type list from stdin '
    print '        Control-C to quit '
    if len (sys.argv) == 1:
        pairs = parse (' '.join (sys.stdin.readlines ()))
    else:
        pairs = parse (' '.join (sys.argv[1:]))
    datum_list = datums (pairs)
    for datum in datum_list:
        printer (datum, datum.get ()) 
    watch_datums (datum_list)
    coredata.loop.run ()
