#!/bin/env python
from os import remove
import socket
from SocketServer import BaseRequestHandler
from SocketServer import TCPServer
from SocketServer import UnixDatagramServer
from thread import start_new_thread


class MonitorServer(TCPServer):

    addr = ('127.0.0.1', 55555)
    allow_reuse_address = True
    running = True

    def serve_forever(self):
        while self.running:
            self.handle_request()

    def shutdown(self):
        self.running = False
        try:
            # tickle myself so serve_forever() finishes
            s = socket.socket()
            s.connect(self.addr)
            s.close()
        except:
            import traceback
            traceback.print_exc()


class SwitchHandler(BaseRequestHandler):

    def handle(self):
        message = self.request[0]
        self.server.setStatus(message)


class SwitchServer(UnixDatagramServer):

    socketname = '/mnt/zope/ZInstanceHome/var/switcher_socket'
    allow_reuse_address = True
    monitor = None
    status = None

    def server_activate(self):
        self.setStatus('open')
        UnixDatagramServer.server_activate(self)

    def startMonitor(self):
        self.monitor = MonitorServer(MonitorServer.addr, BaseRequestHandler)
        start_new_thread(self.monitor.serve_forever, ())
        print 'monitor started'

    def stopMonitor(self):
        if self.monitor is not None:
            self.monitor.shutdown()
            del self.monitor
            self.monitor = None
            print 'monitor stopped'

    def setStatus(self, newstatus):
        if newstatus != self.status:
            if newstatus == 'open':
                self.startMonitor()
                self.status = newstatus
            elif newstatus == 'close':
                self.stopMonitor()
                self.status = newstatus
            else:
                print 'unknown newstatus:', newstatus
        else:
            print 'keeping status:', newstatus


def check_monitor():
    s = socket.socket()
    s.connect(MonitorServer.addr)
    s.close()

def open_monitor():
    s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    s.connect(SwitchServer.socketname)
    s.send('open')
    s.close()

def close_monitor():
    s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    s.connect(SwitchServer.socketname)
    s.send('close')
    s.close()


if __name__ == '__main__':
    try:
        switcher = SwitchServer(SwitchServer.socketname, SwitchHandler)
        switcher.serve_forever()
    finally:
        remove(SwitchServer.socketname)


