"""
    mahali_recorder_service.py

    $Id: mahali_recorder_service.py 476 2015-08-13 21:20:35Z flind $

    This service records command, status, and temperature messages from the control and relay services.

"""

import time
import sys
import os
import io
import optparse
import string
import json
import traceback
import daemon
import redis

from mahali_common import *


#
#---------------------------------------------------------------------------------------
#
#             FUNCTIONS
#
#---------------------------------------------------------------------------------------
#
def parse_command_line():
    parser = optparse.OptionParser()
    parser.add_option("-v", "--verbose",action="store_true", dest="verbose", default=False,help="Print message details.")
    parser.add_option("-d", "--debug",action="store_true", dest="debug", default=False,help="Print debug messages to stdout.")
    parser.add_option("-c", "--config",dest="CPATH",help="Use configuration in path CPATH.")
    parser.add_option("-p", "--path",dest="path",help="Output data to provided <path>.")
    parser.add_option("-f", "--foreground",action="store_true",dest="foreground",help="Execute in foreground and not daemon context.")
    (options, args) = parser.parse_args()

    return (options, args)
# end parse_command_line
#
#---------------------------------------------------------------------------------------
#

def mahali_recorder_service(options):

    start_time = time.time()

    # create redis interface
    redis_db = redis.StrictRedis(host='localhost', port=6379, db=0)

    pubsub = redis_db.pubsub()

    # register with redis in the mahali service list
    mahali_register_service(redis_db, 'mahali-recorder-service')

    # create logging instance
    logQ = redisLoggerQueue('recorder-service',redis_db, options)

    # log startup
    logQ.logInfo('startup')

    mahali_cfg = mahaliConfiguration('mahali-gps-array',options.CPATH, redis_db, logQ)

    config = mahali_cfg.load('mahali-recorder-config')

    if options.path:
        path = options.path
    else:
        path = config['mahali-recorder-service']['recorder_path']


    active_channels = config['mahali-recorder-service']['active']
    print active_channels

    if options.debug:
        logQ.logDebug('recorder path is %s' % (path))

    # setup log recorder files
    # files only get opened when data is available to write

    log_rec = {}

    for l in active_channels:
        lk = 'mahali-metadata-%s' % (l)
        linfo = config[lk]

        if options.debug:
            logQ.logDebug(linfo)

        log_rec[lk] = MahaliDataRecorder(options,logQ,path,linfo['name'],linfo['tag'],linfo['format'],linfo['interval'])

        if options.debug and options.verbose:
            logQ.logDebug('created log recorder for %s' % (linfo['name']))

    # channel subcriptions, static for now using wildcards
    pubsub.psubscribe('mahali-*-command')
    pubsub.psubscribe('mahali-*-status')
    pubsub.psubscribe('mahali-sensor*')
    pubsub.psubscribe('mahali-info-*')
    pubsub.psubscribe('mahali-error-*')
    pubsub.psubscribe('mahali-debug-*')

    last_time = time.time()

    try:
        logQ.logInfo('activate recording')

        for msg in pubsub.listen():

            if msg['type'] == 'psubscribe':
                continue

            if time.time() - last_time > 36400:
                for lk in log_rec:
                    log_rec[lk].resyncTime()

            last_time = time.time()

            if string.split(msg['channel'],'-')[-1] == 'command':
                #if options.debug:
                #    print "command", msg['data']
                if 'command' in active_channels:
                    log_rec['mahali-metadata-command'].log(unicode(msg['data']))

            elif string.split(msg['channel'],'-')[-1] == 'status':
                #if options.debug:
                #    print "status", msg['data']

                if 'status' in active_channels:
                    log_rec['mahali-metadata-status'].log(unicode(msg['data']))

            elif string.split(msg['channel'],'-')[1] == 'sensor':
                #if options.debug:
                #    print "sensor", msg['data']

                if 'sensor' in active_channels:
                    log_rec['mahali-metadata-sensor'].log(unicode(msg['data']))

            elif string.split(msg['channel'],'-')[1] == 'info':
                #if options.debug:
                #    print "info", msg['data']

                if 'info' in active_channels:
                    log_rec['mahali-metadata-info'].log(unicode(msg['data']))

            elif string.split(msg['channel'],'-')[1] == 'error':
                #if options.debug:
                #    print "error", msg['data']
                if 'error' in active_channels:
                    log_rec['mahali-metadata-error'].log(unicode(msg['data']))

            elif string.split(msg['channel'],'-')[1] == 'debug':
                #if options.debug:
                #    print "debug", msg['data']
                if 'debug' in active_channels:
                    log_rec['mahali-metadata-debug'].log(unicode(msg['data']))

            else:
                if options.debug:
                    logQ.logDebug('unrecorded message %s %s', msg['channel'], str(msg['data']))

			# push out heartbeat
            active_time = time.time() - start_time

			# data is a dictionary with key values corresponding to
			# iso8601 timestamp, unix long second timestamp (redundant), type of measurement, and data value
            mahali_send_event(redis_db,logQ,'mahali-recorder-service-heartbeat','heartbeat','active',active_time)

            # mirror state

            state_info = {'start_time':start_time,
                          'active_time':active_time,
                          'update_time':time.time(),
                          'channels':active_channels}

            mahali_set_object(redis_db,logQ,'mahali-recorder-service-state', state_info)


    except KeyboardInterrupt:
		logQ.logInfo("exiting mahali-recorder-service on keyboard interrupt")

    except Exception as eobj:
        exp_str = str(ExceptionString(eobj))
        emsg = "exception: %s. Problem with mahali recorder service" % (exp_str)
        if logQ:
            logQ.logError(emsg)
        else:
            print emsg

    # close out

    for lk in log_rec.keys():
        log_rec[lk].close()

    if options.debug:
        logQ.logDebug('closed all open recorder files')

	# publish shutdown
	logQ.logInfo('shutdown')

    if not mahali_unregister_service(redis_db, 'mahali-recorder-service'):
        sys.exit()

    # deregister with redis
    redis_db.connection_pool.disconnect()

if __name__ == '__main__':

    # parse command line options
    options, args = parse_command_line()

    if options.foreground:
        print "Mahali Recorder Service in DEBUG mode"
        mahali_recorder_service(options)
    else:
         with daemon.DaemonContext():
             mahali_recorder_service(options)
