#!/usr/bin/python

import threading, thread
import time
import socket
import signal
import errno
import fcntl
import os, sys
import logging, ConfigParser

from socket import error as socket_error
from daemon import Daemon
from sensorthread import SensorThread
from controlthread import ControlThread


g_shutdown = False

def sig_handler(signum, frame):
    #print 'handled'
    global g_shutdown
    g_shutdown = True


class SensorDaemon(Daemon):
    def run(self):
        try:
            self.daemon_run()
        except:
            logging.error( "Unexpected error: %s", sys.exc_info())


    """
    Initializes and starts read and control threads.
    Sets up signal handler to catch SIGTERM and do cleanup of threads.
    """
    def daemon_run(self):

        log_file = os.path.expanduser('~/log/sensordaemon.log')

        logging.basicConfig(filename=log_file, format='%(asctime)s (%(name)s) %(levelname)s: %(message)s', level=logging.DEBUG)
        logging.info('### Main thread STARTING ###')

        cfg_file = os.path.expanduser('~/conf/sensor.cfg')
        logging.info('Reading config from %s', cfg_file)

        config = ConfigParser.RawConfigParser()
        config.read(cfg_file)

        # Set up signal handling.
        pipe_r, pipe_w = os.pipe()
        flags = fcntl.fcntl(pipe_w, fcntl.F_GETFL, 0)
        flags |= os.O_NONBLOCK
        flags = fcntl.fcntl(pipe_w, fcntl.F_SETFL, flags)
        signal.set_wakeup_fd(pipe_w)

        signal.signal(signal.SIGTERM, sig_handler)

        # Create new threads
        logging.info('Creating threads')
        sensor_thread = SensorThread(config)
        control_thread = ControlThread(config,sensor_thread)
        
        # Start threads
        logging.info('Starting threads')
        sensor_thread.start()
        control_thread.start()

        threads = []
        threads.append(sensor_thread)
        threads.append(control_thread)

        logging.debug('Main entering wait-state')
        # Sleep until woken by a signal.
        while not g_shutdown:
            while True:
                try:
                    os.read(pipe_r, 1)
                    break
                except OSError, e:
                    if e.errno != errno.EINTR:
                        raise

        logging.info('Daemon is shutting down')

        # Shutdown work threads gracefully.
        for t in threads:
            t.shutdown()
            t.join()

        logging.info('### Main thread EXITING ###')


if __name__ == "__main__":
    
    daemon = SensorDaemon('/tmp/sensordaemon.pid')
    
    if len(sys.argv) == 2:
        if 'start' == sys.argv[1]:
            daemon.start()
        elif 'stop' == sys.argv[1]:
            daemon.stop()
        elif 'restart' == sys.argv[1]:
            daemon.restart()
        elif 'debug' == sys.argv[1]:
            daemon.daemon_run()
        else:
            print "Unknown command"
            sys.exit(2)
        sys.exit(0)
    else:
        print "usage: %s start|stop|restart" % sys.argv[0]
        sys.exit(2)

